Skip to content

Commit d3a6f6c

Browse files
authored
Remove std::stof uses (#83015)
Let callers explicitly handle failures, instead of relying on whatever exceptions that std::stof throws.
1 parent 4fbcae4 commit d3a6f6c

File tree

7 files changed

+36
-14
lines changed

7 files changed

+36
-14
lines changed

src/butchery_requirements.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
#include <cstddef>
44
#include <functional>
5+
#include <optional>
56
#include <string>
67

8+
#include "cata_utility.h"
79
#include "creature.h"
810
#include "debug.h"
911
#include "enum_conversions.h"
@@ -58,7 +60,11 @@ bool butchery_requirements::is_valid() const
5860
void butchery_requirements::load( const JsonObject &jo, std::string_view )
5961
{
6062
for( const JsonMember member : jo.get_object( "requirements" ) ) {
61-
float modifier = std::stof( member.name() );
63+
std::optional<double> mod_val = svtod( member.name() );
64+
if( !mod_val.has_value() ) {
65+
jo.throw_error( "Invalid key for requirements, cannot convert to float" );
66+
}
67+
float modifier = mod_val.value();
6268
requirements.emplace( modifier, std::map<creature_size, std::map<butcher_type, requirement_id>> {} );
6369

6470
int critter_size = 1;

src/cata_utility.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ std::string io::enum_to_string<aggregate_type>( aggregate_type agg )
915915
cata_fatal( "Invalid aggregate type." );
916916
}
917917

918-
std::optional<double> svtod( std::string_view token )
918+
std::optional<double> svtod( std::string_view token, bool debugmsg_on_fail )
919919
{
920920
char *pEnd = nullptr;
921921
double const val = std::strtod( token.data(), &pEnd );
@@ -929,7 +929,9 @@ std::optional<double> svtod( std::string_view token )
929929
unlocalized[pEnd - token.data()] = block == ',' ? '.' : ',';
930930
return svtod( unlocalized );
931931
}
932-
debugmsg( R"(Failed to convert string value "%s" to double: %s)", token, std::strerror( errno ) );
932+
if( debugmsg_on_fail ) {
933+
debugmsg( R"(Failed to convert string value "%s" to double: %s)", token, std::strerror( errno ) );
934+
}
933935

934936
errno = 0;
935937

src/cata_utility.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,6 @@ struct overloaded : Ts... {
768768
template <class... Ts>
769769
explicit overloaded( Ts... ) -> overloaded<Ts...>;
770770

771-
std::optional<double> svtod( std::string_view token );
771+
std::optional<double> svtod( std::string_view token, bool debugmsg_on_fail = true );
772772

773773
#endif // CATA_SRC_CATA_UTILITY_H

src/math_parser_diag_value.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,12 @@ void diag_value::_deserialize( const JsonValue &jsin, bool allow_legacy )
362362
// inf and nan
363363
std::string str;
364364
jo.read( "dbl", str );
365-
data = std::stof( str );
365+
std::optional<double> opt = svtod( str );
366+
if( !opt.has_value() ) {
367+
jo.allow_omitted_members();
368+
jo.throw_error( "Invalid dbl value" );
369+
}
370+
data = opt.value();
366371
} else {
367372
jo.allow_omitted_members();
368373
throw JsonError( "invalid diag_value object" );

src/options.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4014,7 +4014,7 @@ std::string options_manager::migrateOptionValue( const std::string &name,
40144014
{
40154015
//TODO: Remove after stable after world option reserialising is added
40164016
if( name == "MONSTER_UPGRADE_FACTOR" ) {
4017-
const float new_value = std::stof( val ) / 4.0f;
4017+
const float new_value = svtod( val ).value_or( 4.0 ) / 4.0f;
40184018
std::ostringstream ssTemp;
40194019
ssTemp.imbue( std::locale::classic() );
40204020
ssTemp.precision( 2 );

src/proficiency_ui.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include <optional>
55
#include <ostream>
66
#include <set>
7-
#include <stdexcept>
87
#include <string>
98
#include <utility>
109
#include <vector>
@@ -124,14 +123,14 @@ void prof_window::filter()
124123
}
125124
float prog_val = 0.0f;
126125
if( prefix == _prof_filter_prefix::AS_PROGRESS ) {
127-
try {
128-
prog_val = std::stof( qry );
129-
} catch( const std::invalid_argument &e ) {
126+
std::optional<double> v = svtod( qry, false );
127+
if( !v.has_value() ) {
130128
// User mistyped query. Not severe enough for debugmsg.
131129
DebugLog( DebugLevel::D_WARNING, DebugClass::D_GAME ) <<
132-
"Malformed proficiency query \"" << filter_str << "\": " << e.what();
130+
"Malformed proficiency query \"" << filter_str << "\"";
133131
return;
134132
}
133+
prog_val = v.value();
135134
}
136135
for( display_prof_deps &dp : all_profs ) {
137136
if( prefix == _prof_filter_prefix::AS_PROGRESS ) {

src/units.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include "units.h"
22

33
#include <cstdint>
4+
#include <optional>
45

56
#include "calendar.h"
7+
#include "cata_utility.h"
68
#include "json.h"
79
#include "string_formatter.h"
810
#include "translations.h"
@@ -64,7 +66,11 @@ void specific_energy::serialize( JsonOut &jsout ) const
6466
template<>
6567
void specific_energy::deserialize( const JsonValue &jv )
6668
{
67-
*this = units::from_joule_per_gram( std::stof( jv.get_string() ) );
69+
std::optional<double> v = svtod( jv.get_string() );
70+
if( !v.has_value() ) {
71+
jv.throw_error( "Invalid double" );
72+
}
73+
*this = units::from_joule_per_gram( v.value() );
6874
}
6975

7076
template<>
@@ -85,8 +91,12 @@ void temperature_delta::deserialize( const JsonValue &jv )
8591
if( jv.test_int() ) {
8692
*this = from_legacy_bodypart_temp_delta( jv.get_int() );
8793
} else {
88-
// super gross
89-
*this = from_kelvin_delta( std::stof( jv.get_string() ) );
94+
// gross
95+
std::optional<double> v = svtod( jv.get_string() );
96+
if( !v.has_value() ) {
97+
jv.throw_error( "Invalid double" );
98+
}
99+
*this = from_kelvin_delta( v.value() );
90100
}
91101
}
92102

0 commit comments

Comments
 (0)