mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-06 16:56:57 +08:00
Prevent fast_float::from_chars from parsing whitespaces and leading '+' sign, similar to MSVC and integer LLVM std::from_chars behavior. See C++17 20.19.3.(7.1) and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r5.html
This commit is contained in:
parent
d4bc0f28a2
commit
87e5a95585
@ -62,7 +62,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
||||
answer.valid = false;
|
||||
answer.too_many_digits = false;
|
||||
answer.negative = (*p == '-');
|
||||
if ((*p == '-') || (*p == '+')) {
|
||||
if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||
++p;
|
||||
if (p == pend) {
|
||||
return answer;
|
||||
@ -118,7 +118,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
||||
if ((p != pend) && ('-' == *p)) {
|
||||
neg_exp = true;
|
||||
++p;
|
||||
} else if ((p != pend) && ('+' == *p)) {
|
||||
} else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
|
||||
++p;
|
||||
}
|
||||
if ((p == pend) || !is_integer(*p)) {
|
||||
@ -200,9 +200,8 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n
|
||||
answer.num_digits = 0;
|
||||
answer.decimal_point = 0;
|
||||
answer.truncated = false;
|
||||
// any whitespace has been skipped.
|
||||
answer.negative = (*p == '-');
|
||||
if ((*p == '-') || (*p == '+')) {
|
||||
if (*p == '-') { // C++17 20.19.3.(7.1) explicitly forbids '+' sign here
|
||||
++p;
|
||||
}
|
||||
// skip leading zeroes
|
||||
@ -275,7 +274,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n
|
||||
if ((p != pend) && ('-' == *p)) {
|
||||
neg_exp = true;
|
||||
++p;
|
||||
} else if ((p != pend) && ('+' == *p)) {
|
||||
} else if ((p != pend) && ('+' == *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1)
|
||||
++p;
|
||||
}
|
||||
int32_t exp_number = 0; // exponential part
|
||||
|
||||
@ -78,22 +78,6 @@ inline bool fastfloat_strncasecmp(const char *input1, const char *input2,
|
||||
#error "FLT_EVAL_METHOD should be defined, please include cfloat."
|
||||
#endif
|
||||
|
||||
inline bool is_space(uint8_t c) {
|
||||
static const bool table[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
return table[c];
|
||||
}
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t max_digits = 768;
|
||||
constexpr uint32_t max_digit_without_overflow = 19;
|
||||
|
||||
@ -25,11 +25,9 @@ from_chars_result parse_infnan(const char *first, const char *last, T &value) n
|
||||
answer.ptr = first;
|
||||
answer.ec = std::errc(); // be optimistic
|
||||
bool minusSign = false;
|
||||
if (*first == '-') { // assume first < last, so dereference without checks
|
||||
if (*first == '-') { // assume first < last, so dereference without checks; C++17 20.19.3.(7.1) explicitly forbids '+' here
|
||||
minusSign = true;
|
||||
++first;
|
||||
} else if( *first == '+' ) { // C++17 20.19.3.7 explicitly forbids '+' here, but anyway
|
||||
++first;
|
||||
}
|
||||
if (last - first >= 3) {
|
||||
if (fastfloat_strncasecmp(first, "nan", 3)) {
|
||||
@ -91,9 +89,6 @@ from_chars_result from_chars(const char *first, const char *last,
|
||||
|
||||
|
||||
from_chars_result answer;
|
||||
while ((first != last) && fast_float::is_space(uint8_t(*first))) {
|
||||
first++;
|
||||
}
|
||||
if (first == last) {
|
||||
answer.ec = std::errc::invalid_argument;
|
||||
answer.ptr = first;
|
||||
|
||||
@ -430,7 +430,7 @@ TEST_CASE("64bit.general") {
|
||||
verify("-1.7664960224650106892054063261344555646357024359107788800000000000e+53", -1.7664960224650106892054063261344555646357024359107788800000000000e+53);
|
||||
verify("-2.1470977154320536489471030463761883783915110400000000000000000000e+45", -2.1470977154320536489471030463761883783915110400000000000000000000e+45);
|
||||
verify("-4.4900312744003159009338275160799498340862630046359789166919680000e+61", -4.4900312744003159009338275160799498340862630046359789166919680000e+61);
|
||||
verify("+1", 1.0);
|
||||
verify("1", 1.0);
|
||||
verify("1.797693134862315700000000000000001e308", 1.7976931348623157e308);
|
||||
verify("3e-324", 0x0.0000000000001p-1022);
|
||||
verify("1.00000006e+09", 0x1.dcd651ep+29);
|
||||
@ -532,7 +532,7 @@ TEST_CASE("32bit.general") {
|
||||
verify("4.7019774032891500318749461488889827112746622270883500860350068251e-38",4.7019774032891500318749461488889827112746622270883500860350068251e-38f);
|
||||
verify("3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679", 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f);
|
||||
verify("2.3509887016445750159374730744444913556373311135441750430175034126e-38", 2.3509887016445750159374730744444913556373311135441750430175034126e-38f);
|
||||
verify("+1", 1.f);
|
||||
verify("1", 1.f);
|
||||
verify("7.0060e-46", 0.f);
|
||||
verify("3.4028234664e38", 0x1.fffffep+127f);
|
||||
verify("3.4028234665e38", 0x1.fffffep+127f);
|
||||
|
||||
@ -125,38 +125,38 @@ bool partow_test() {
|
||||
const std::string strint_list[] = { "9007199254740993", "9007199254740994", "9007199254740995" ,
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"917049", "4931205", "6768064", "6884243", "5647132", "7371203", "-8629878", "4941840", "4543268", "1075600",
|
||||
"+290", "823", "+111", "715", "-866", "+367", "666", "-706", "850", "-161",
|
||||
"9922547", "6960207", "1883152", "2300759", "-279294", "4187292", "3699841", "+8386395", "-1441129", "-887892",
|
||||
"290", "823", "111", "715", "-866", "367", "666", "-706", "850", "-161",
|
||||
"9922547", "6960207", "1883152", "2300759", "-279294", "4187292", "3699841", "8386395", "-1441129", "-887892",
|
||||
"-635422", "9742573", "2326186", "-5903851", "5648486", "3057647", "2980079", "2957468", "7929158", "1925615",
|
||||
"879", "+130", "292", "+705", "817", "446", "576", "750", "523", "-527",
|
||||
"4365041", "5624958", "8990205", "2652177", "3993588", "-298316", "+2901599", "3887387", "-5202979", "1196268",
|
||||
"879", "130", "292", "705", "817", "446", "576", "750", "523", "-527",
|
||||
"4365041", "5624958", "8990205", "2652177", "3993588", "-298316", "2901599", "3887387", "-5202979", "1196268",
|
||||
"5968501", "7619928", "3565643", "1885272", "-749485", "2961381", "2982579", "2387454", "4250081", "5958205",
|
||||
"00000", "00001", "00002", "+00003", "00004", "00005", "00006", "00007", "00008", "+00009",
|
||||
"4907034", "2592882", "3269234", "549815", "6256292", "9721039", "-595225", "+5587491", "4596297", "-3885009",
|
||||
"673", "-899", "174", "354", "870", "147", "898", "-510", "369", "+859",
|
||||
"00000", "00001", "00002", "00003", "00004", "00005", "00006", "00007", "00008", "00009",
|
||||
"4907034", "2592882", "3269234", "549815", "6256292", "9721039", "-595225", "5587491", "4596297", "-3885009",
|
||||
"673", "-899", "174", "354", "870", "147", "898", "-510", "369", "859",
|
||||
"6518423", "5149762", "8834164", "-8085586", "3233120", "8166948", "4172345", "6735549", "-934295", "9481935",
|
||||
"-430406", "6932717", "4087292", "4047263", "3236400", "-3863050", "4312079", "6956261", "5689446", "3871332",
|
||||
"+535", "691", "+326", "-409", "704", "-568", "+301", "951", "121", "384",
|
||||
"535", "691", "326", "-409", "704", "-568", "301", "951", "121", "384",
|
||||
"4969414", "9378599", "7971781", "5380630", "5001363", "1715827", "6044615", "9118925", "9956168", "-8865496",
|
||||
"5962464", "7408980", "6646513", "-634564", "4188330", "9805948", "5625691", "+7641113", "-4212929", "7802447",
|
||||
"+0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9",
|
||||
"5962464", "7408980", "6646513", "-634564", "4188330", "9805948", "5625691", "7641113", "-4212929", "7802447",
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
||||
"2174248", "7449361", "9896659", "-25961", "1706598", "2412368", "-4617035", "6314554", "2225957", "7521434",
|
||||
"-9530566", "3914164", "2394759", "7157744", "9919392", "6406949", "-744004", "9899789", "8380325", "-1416284",
|
||||
"3402833", "2150043", "5191009", "8979538", "9565778", "3750211", "7304823", "2829359", "6544236", "-615740",
|
||||
"363", "-627", "129", "+656", "135", "113", "381", "+646", "198", "38",
|
||||
"363", "-627", "129", "656", "135", "113", "381", "646", "198", "38",
|
||||
"8060564", "-176752", "1184717", "-666343", "-1273292", "-485827", "6241066", "6579411", "8093119", "7481306",
|
||||
"-4924485", "7467889", "9813178", "7927100", "+3614859", "7293354", "9232973", "4323115", "1133911", "+9511638",
|
||||
"-4924485", "7467889", "9813178", "7927100", "3614859", "7293354", "9232973", "4323115", "1133911", "9511638",
|
||||
"4443188", "2289448", "5639726", "9073898", "8540394", "5389992", "1397726", "-589230", "1017086", "1852330",
|
||||
"-840", "267", "201", "533", "-675", "494", "315", "706", "-920", "784",
|
||||
"9097353", "6002251", "-308780", "-3830169", "4340467", "2235284", "3314444", "1085967", "4152107", "+5431117",
|
||||
"9097353", "6002251", "-308780", "-3830169", "4340467", "2235284", "3314444", "1085967", "4152107", "5431117",
|
||||
"-0000", "-0001", "-0002", "-0003", "-0004", "-0005", "-0006", "-0007", "-0008", "-0009",
|
||||
"-444999", "2136400", "6925907", "6990614", "3588271", "8422028", "-4034772", "5804039", "-6740545", "9381873",
|
||||
"-924923", "1652367", "2302616", "6776663", "2567821", "-248935", "2587688", "7076742", "-6461467", "1562896",
|
||||
"-768116", "2338768", "9887307", "9992184", "2045182", "2797589", "9784597", "9696554", "5113329", "1067216",
|
||||
"-76247763", "58169007", "29408062", "85342511", "42092201", "-95817703", "-1912517", "-26275135", "54656606", "-58188878",
|
||||
"+473", "74", "374", "-64", "266", "+715", "937", "-249", "249", "780",
|
||||
"473", "74", "374", "-64", "266", "715", "937", "-249", "249", "780",
|
||||
"3907360", "-23063423", "59062754", "83711047", "-95221044", "34894840", "-38562139", "-82018330", "14226223", "-10799717",
|
||||
"8529722", "88961903", "25608618", "-39988247", "33228241", "+38598533", "21161480", "-33723784", "8873948", "96505557",
|
||||
"8529722", "88961903", "25608618", "-39988247", "33228241", "38598533", "21161480", "-33723784", "8873948", "96505557",
|
||||
"-47385048", "-79413272", "-85904404", "87791158", "49194195", "13051222", "57773302", "31904423", "3142966", "27846156",
|
||||
"7420011", "-72376922", "-68873971", "23765361", "4040725", "-22359806", "85777219", "10099223", "-90364256", "-40158172",
|
||||
"-7948696", "-64344821", "34404238", "84037448", "-85084788", "-42078409", "-56550310", "96898389", "-595829", "-73166703",
|
||||
@ -165,20 +165,20 @@ bool partow_test() {
|
||||
"-82838342", "64441808", "43641062", "-64419642", "-44421934", "75232413", "-75773725", "-89139509", "12812089", "-97633526",
|
||||
"36090916", "-57706234", "17804655", "4189936", "-4100124", "38803710", "-39735126", "-62397437", "75801648", "51302332",
|
||||
"73433906", "13015224", "-12624818", "91360377", "11576319", "-54467535", "8892431", "36319780", "38832042", "50172572",
|
||||
"-317", "109", "-888", "302", "-463", "716", "+916", "665", "826", "513",
|
||||
"-317", "109", "-888", "302", "-463", "716", "916", "665", "826", "513",
|
||||
"42423473", "41078812", "40445652", "-76722281", "95092224", "12075234", "-4045888", "-74396490", "-57304222", "-21726885",
|
||||
"92038121", "-31899682", "21589254", "-30260046", "56000244", "69686659", "+93327838", "96882881", "-91419389", "77529147",
|
||||
"+43288506", "1192435", "-74095920", "76756590", "-31184683", "-35716724", "9451980", "-63168350", "62864002", "26283194",
|
||||
"37188395", "29151634", "99343471", "-69450330", "-55680090", "-64957599", "47577948", "47107924", "2490477", "+48633003",
|
||||
"92038121", "-31899682", "21589254", "-30260046", "56000244", "69686659", "93327838", "96882881", "-91419389", "77529147",
|
||||
"43288506", "1192435", "-74095920", "76756590", "-31184683", "-35716724", "9451980", "-63168350", "62864002", "26283194",
|
||||
"37188395", "29151634", "99343471", "-69450330", "-55680090", "-64957599", "47577948", "47107924", "2490477", "48633003",
|
||||
"-82740809", "-24122215", "67301713", "-63649610", "75499016", "82746620", "17052193", "4602244", "-32721165", "20837836",
|
||||
"674", "+467", "+706", "889", "172", "+282", "-795", "188", "+87", "153",
|
||||
"674", "467", "706", "889", "172", "282", "-795", "188", "87", "153",
|
||||
"64501793", "53146328", "5152287", "-9674493", "68105580", "57245637", "39740229", "-74071854", "86777268", "86484437",
|
||||
"-86962508", "12644427", "-62944073", "59539680", "43340539", "30661534", "20143968", "-68183731", "-48250926", "42669063",
|
||||
"+000", "+001", "+002", "+003", "+004", "+005", "+006", "+007", "+008", "+009",
|
||||
"000", "001", "002", "003", "004", "005", "006", "007", "008", "009",
|
||||
"2147483499", "71", "2147483462", "73", "2147483425", "77", "2147483388",
|
||||
"87736852", "-4444906", "-48094147", "54774735", "54571890", "-22473078", "95053418", "393654", "-33229960", "32276798",
|
||||
"-48361110", "44295939", "-79813406", "11630865", "38544571", "70972830", "-9821748", "-60965384", "-13096675", "-24569041",
|
||||
"708", "-467", "-794", "610", "+929", "766", "152", "482", "397", "-191",
|
||||
"708", "-467", "-794", "610", "929", "766", "152", "482", "397", "-191",
|
||||
"97233152", "51028396", "-13796948", "95437272", "71352512", "-83233730", "-68517318", "61832742", "-42667174", "-18002395",
|
||||
"-92239407", "12701336", "-63830875", "41514172", "-5726049", "18668677", "69555144", "-13737009", "-22626233", "-55078143",
|
||||
"00", "11", "22", "33", "44", "-00", "-11", "-22", "-33", "-44",
|
||||
@ -216,13 +216,13 @@ bool partow_test() {
|
||||
"0055555555", "0066666666", "0077777777", "0088888888", "0099999999", "-055555555", "-066666666", "-077777777", "-099999999",
|
||||
"0555555555", "0666666666", "0777777777", "0888888888", "0999999999", "-555555555", "-666666666", "-777777777", "-999999999",
|
||||
"-2147483426", "101", "-2147483389", "103", "-2147483352", "105", "-2147483315",
|
||||
"0000001234567890", "+0000001234567890", "-0000001234567890",
|
||||
"000001234567890", "+000001234567890", "-000001234567890",
|
||||
"00001234567890", "+00001234567890", "-00001234567890",
|
||||
"0001234567890", "+0001234567890", "-0001234567890",
|
||||
"001234567890", "+001234567890", "-001234567890",
|
||||
"01234567890", "+01234567890", "-01234567890",
|
||||
"1234567890", "+1234567890", "-1234567890",
|
||||
"0000001234567890", "0000001234567890", "-0000001234567890",
|
||||
"000001234567890", "000001234567890", "-000001234567890",
|
||||
"00001234567890", "00001234567890", "-00001234567890",
|
||||
"0001234567890", "0001234567890", "-0001234567890",
|
||||
"001234567890", "001234567890", "-001234567890",
|
||||
"01234567890", "01234567890", "-01234567890",
|
||||
"1234567890", "1234567890", "-1234567890",
|
||||
};
|
||||
for(const std::string& st : strint_list) {
|
||||
T expected_value;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user