@@ -1263,6 +1263,20 @@ Return a hexadecimal representation of a floating-point number.\n\
12631263>>> 3.14159.hex()\n\
12641264'0x1.921f9f01b866ep+1'" );
12651265
1266+ /* Case-insensitive string match used for nan and inf detection. t should be
1267+ lower-case and null-terminated. Return a nonzero result if the first
1268+ strlen(t) characters of s match t and 0 otherwise. */
1269+
1270+ static int
1271+ case_insensitive_match (const char * s , const char * t )
1272+ {
1273+ while (* t && tolower (* s ) == * t ) {
1274+ s ++ ;
1275+ t ++ ;
1276+ }
1277+ return * t ? 0 : 1 ;
1278+ }
1279+
12661280/* Convert a hexadecimal string to a float. */
12671281
12681282static PyObject *
@@ -1329,7 +1343,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
13291343 ********************/
13301344
13311345 /* leading whitespace and optional sign */
1332- while (isspace (* s ))
1346+ while (* s && isspace (Py_CHARMASK ( * s ) ))
13331347 s ++ ;
13341348 if (* s == '-' ) {
13351349 s ++ ;
@@ -1339,13 +1353,20 @@ float_fromhex(PyObject *cls, PyObject *arg)
13391353 s ++ ;
13401354
13411355 /* infinities and nans */
1342- if (PyOS_strnicmp (s , "nan" , 4 ) == 0 ) {
1343- x = Py_NAN ;
1356+ if (* s == 'i' || * s == 'I' ) {
1357+ if (!case_insensitive_match (s + 1 , "nf" ))
1358+ goto parse_error ;
1359+ s += 3 ;
1360+ x = Py_HUGE_VAL ;
1361+ if (case_insensitive_match (s , "inity" ))
1362+ s += 5 ;
13441363 goto finished ;
13451364 }
1346- if (PyOS_strnicmp (s , "inf" , 4 ) == 0 ||
1347- PyOS_strnicmp (s , "infinity" , 9 ) == 0 ) {
1348- x = sign * Py_HUGE_VAL ;
1365+ if (* s == 'n' || * s == 'N' ) {
1366+ if (!case_insensitive_match (s + 1 , "an" ))
1367+ goto parse_error ;
1368+ s += 3 ;
1369+ x = Py_NAN ;
13491370 goto finished ;
13501371 }
13511372
@@ -1398,12 +1419,6 @@ float_fromhex(PyObject *cls, PyObject *arg)
13981419 else
13991420 exp = 0 ;
14001421
1401- /* optional trailing whitespace leading to the end of the string */
1402- while (isspace (* s ))
1403- s ++ ;
1404- if (s != s_end )
1405- goto parse_error ;
1406-
14071422/* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */
14081423#define HEX_DIGIT (j ) hex_from_char(*((j) < fdigits ? \
14091424 coeff_end-(j) : \
@@ -1417,7 +1432,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
14171432 while (ndigits > 0 && HEX_DIGIT (ndigits - 1 ) == 0 )
14181433 ndigits -- ;
14191434 if (ndigits == 0 || exp < LONG_MIN /2 ) {
1420- x = sign * 0.0 ;
1435+ x = 0.0 ;
14211436 goto finished ;
14221437 }
14231438 if (exp > LONG_MAX /2 )
@@ -1433,7 +1448,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
14331448
14341449 /* catch almost all nonextreme cases of overflow and underflow here */
14351450 if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG ) {
1436- x = sign * 0.0 ;
1451+ x = 0.0 ;
14371452 goto finished ;
14381453 }
14391454 if (top_exp > DBL_MAX_EXP )
@@ -1448,7 +1463,7 @@ float_fromhex(PyObject *cls, PyObject *arg)
14481463 /* no rounding required */
14491464 for (i = ndigits - 1 ; i >= 0 ; i -- )
14501465 x = 16.0 * x + HEX_DIGIT (i );
1451- x = sign * ldexp (x , (int )(exp ));
1466+ x = ldexp (x , (int )(exp ));
14521467 goto finished ;
14531468 }
14541469 /* rounding required. key_digit is the index of the hex digit
@@ -1482,10 +1497,15 @@ float_fromhex(PyObject *cls, PyObject *arg)
14821497 goto overflow_error ;
14831498 }
14841499 }
1485- x = sign * ldexp (x , (int )(exp + 4 * key_digit ));
1500+ x = ldexp (x , (int )(exp + 4 * key_digit ));
14861501
14871502 finished :
1488- result_as_float = Py_BuildValue ("(d)" , x );
1503+ /* optional trailing whitespace leading to the end of the string */
1504+ while (* s && isspace (Py_CHARMASK (* s )))
1505+ s ++ ;
1506+ if (s != s_end )
1507+ goto parse_error ;
1508+ result_as_float = Py_BuildValue ("(d)" , sign * x );
14891509 if (result_as_float == NULL )
14901510 return NULL ;
14911511 result = PyObject_CallObject (cls , result_as_float );
0 commit comments