@@ -243,21 +243,22 @@ static zend_never_inline int ZEND_FASTCALL _zendi_try_convert_scalar_to_number(z
243
243
ZVAL_LONG (holder , 1 );
244
244
return SUCCESS ;
245
245
case IS_STRING :
246
- if (( Z_TYPE_INFO_P ( holder ) = is_numeric_string ( Z_STRVAL_P ( op ), Z_STRLEN_P ( op ),
247
- & Z_LVAL_P ( holder ), & Z_DVAL_P ( holder ), false)) == 0 ) {
248
- /* Not strictly numeric
249
- * For BC reasons warn on leading numeric strings */
250
- if (( Z_TYPE_INFO_P ( holder ) = is_numeric_string ( Z_STRVAL_P ( op ), Z_STRLEN_P ( op ),
251
- & Z_LVAL_P ( holder ), & Z_DVAL_P ( holder ), /* allow errors */ true)) == 0 ) {
252
- /* Will lead to invalid OP type error */
253
- return FAILURE ;
254
- }
246
+ {
247
+ bool trailing_data = false;
248
+ /* For BC reasons we allow errors so that we can warn on leading numeric string */
249
+ if ( 0 == ( Z_TYPE_INFO_P ( holder ) = is_numeric_string_ex ( Z_STRVAL_P ( op ), Z_STRLEN_P ( op ),
250
+ & Z_LVAL_P ( holder ), & Z_DVAL_P ( holder ), /* allow errors */ true, NULL , & trailing_data ))) {
251
+ /* Will lead to invalid OP type error */
252
+ return FAILURE ;
253
+ }
254
+ if ( UNEXPECTED ( trailing_data )) {
255
255
zend_error (E_WARNING , "A non-numeric value encountered" );
256
256
if (UNEXPECTED (EG (exception ))) {
257
257
return FAILURE ;
258
258
}
259
259
}
260
260
return SUCCESS ;
261
+ }
261
262
case IS_OBJECT :
262
263
if (Z_OBJ_HT_P (op )-> cast_object (Z_OBJ_P (op ), holder , _IS_NUMBER ) == FAILURE
263
264
|| EG (exception )) {
@@ -300,32 +301,29 @@ static zend_never_inline zend_long ZEND_FASTCALL zendi_try_get_long(zval *op, ze
300
301
zend_uchar type ;
301
302
zend_long lval ;
302
303
double dval ;
303
- if (0 == (type = is_numeric_string (Z_STRVAL_P (op ), Z_STRLEN_P (op ), & lval , & dval , false))) {
304
- /* Not strictly numeric
305
- * For BC reasons warn on leading numeric strings */
306
- if (0 == (type = is_numeric_string (Z_STRVAL_P (op ), Z_STRLEN_P (op ), & lval , & dval ,
307
- /* allow errors */ true))) {
308
- /* Will lead to invalid OP type error */
309
- * failed = 1 ;
310
- return 0 ;
311
- }
312
- zend_error (E_WARNING , "A non-numeric value encountered" );
313
- if (UNEXPECTED (EG (exception ))) {
314
- * failed = 1 ;
315
- }
316
- if (type == IS_LONG ) {
317
- return lval ;
318
- } else {
319
- /* Previously we used strtol here, not is_numeric_string,
320
- * and strtol gives you LONG_MAX/_MIN on overflow.
321
- * We use use saturating conversion to emulate strtol()'s
322
- * behaviour.
323
- */
324
- return zend_dval_to_lval_cap (dval );
325
- }
304
+ bool trailing_data = false;
305
+
306
+ /* For BC reasons we allow errors so that we can warn on leading numeric string */
307
+ type = is_numeric_string_ex (Z_STRVAL_P (op ), Z_STRLEN_P (op ), & lval , & dval ,
308
+ /* allow errors */ true, NULL , & trailing_data );
309
+ if (type == 0 ) {
310
+ * failed = 1 ;
311
+ return 0 ;
326
312
} else if (EXPECTED (type == IS_LONG )) {
313
+ if (UNEXPECTED (trailing_data )) {
314
+ zend_error (E_WARNING , "A non-numeric value encountered" );
315
+ if (UNEXPECTED (EG (exception ))) {
316
+ * failed = 1 ;
317
+ }
318
+ }
327
319
return lval ;
328
320
} else {
321
+ if (trailing_data ) {
322
+ zend_error (E_WARNING , "A non-numeric value encountered" );
323
+ if (UNEXPECTED (EG (exception ))) {
324
+ * failed = 1 ;
325
+ }
326
+ }
329
327
/* Previously we used strtol here, not is_numeric_string,
330
328
* and strtol gives you LONG_MAX/_MIN on overflow.
331
329
* We use use saturating conversion to emulate strtol()'s
@@ -2831,8 +2829,8 @@ ZEND_API int ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2) /
2831
2829
zend_long lval1 = 0 , lval2 = 0 ;
2832
2830
double dval1 = 0.0 , dval2 = 0.0 ;
2833
2831
2834
- if ((ret1 = is_numeric_string_ex (s1 -> val , s1 -> len , & lval1 , & dval1 , false, & oflow1 )) &&
2835
- (ret2 = is_numeric_string_ex (s2 -> val , s2 -> len , & lval2 , & dval2 , false, & oflow2 ))) {
2832
+ if ((ret1 = is_numeric_string_ex (s1 -> val , s1 -> len , & lval1 , & dval1 , false, & oflow1 , NULL )) &&
2833
+ (ret2 = is_numeric_string_ex (s2 -> val , s2 -> len , & lval2 , & dval2 , false, & oflow2 , NULL ))) {
2836
2834
#if ZEND_ULONG_MAX == 0xFFFFFFFF
2837
2835
if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
2838
2836
((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/ )
@@ -2879,8 +2877,8 @@ ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2)
2879
2877
zend_long lval1 = 0 , lval2 = 0 ;
2880
2878
double dval1 = 0.0 , dval2 = 0.0 ;
2881
2879
2882
- if ((ret1 = is_numeric_string_ex (s1 -> val , s1 -> len , & lval1 , & dval1 , false, & oflow1 )) &&
2883
- (ret2 = is_numeric_string_ex (s2 -> val , s2 -> len , & lval2 , & dval2 , false, & oflow2 ))) {
2880
+ if ((ret1 = is_numeric_string_ex (s1 -> val , s1 -> len , & lval1 , & dval1 , false, & oflow1 , NULL )) &&
2881
+ (ret2 = is_numeric_string_ex (s2 -> val , s2 -> len , & lval2 , & dval2 , false, & oflow2 , NULL ))) {
2884
2882
#if ZEND_ULONG_MAX == 0xFFFFFFFF
2885
2883
if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
2886
2884
((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/ )
@@ -2982,7 +2980,7 @@ ZEND_API zend_uchar ZEND_FASTCALL is_numeric_str_function(const zend_string *str
2982
2980
/* }}} */
2983
2981
2984
2982
ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex (const char * str , size_t length , zend_long * lval ,
2985
- double * dval , bool allow_errors , int * oflow_info ) /* {{{ */
2983
+ double * dval , bool allow_errors , int * oflow_info , bool * trailing_data ) /* {{{ */
2986
2984
{
2987
2985
const char * ptr ;
2988
2986
int digits = 0 , dp_or_e = 0 ;
@@ -2998,6 +2996,9 @@ ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex(const char *str, size_t
2998
2996
if (oflow_info != NULL ) {
2999
2997
* oflow_info = 0 ;
3000
2998
}
2999
+ if (trailing_data != NULL ) {
3000
+ * trailing_data = false;
3001
+ }
3001
3002
3002
3003
/* Skip any whitespace
3003
3004
* This is much faster than the isspace() function */
@@ -3077,6 +3078,9 @@ ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex(const char *str, size_t
3077
3078
if (!allow_errors ) {
3078
3079
return 0 ;
3079
3080
}
3081
+ if (trailing_data != NULL ) {
3082
+ * trailing_data = true;
3083
+ }
3080
3084
}
3081
3085
}
3082
3086
0 commit comments