@@ -669,6 +669,9 @@ ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */
669669
670670ZEND_API void ZEND_FASTCALL convert_to_null (zval * op ) /* {{{ */
671671{
672+ if (UNEXPECTED (Z_TYPE_P (op ) == IS_DOUBLE && zend_isnan (Z_DVAL_P (op )))) {
673+ zend_nan_coerced_to_type_warning (IS_NULL );
674+ }
672675 zval_ptr_dtor (op );
673676 ZVAL_NULL (op );
674677}
@@ -697,6 +700,9 @@ ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
697700 ZVAL_BOOL (op , Z_LVAL_P (op ) ? 1 : 0 );
698701 break ;
699702 case IS_DOUBLE :
703+ if (UNEXPECTED (zend_isnan (Z_DVAL_P (op )))) {
704+ zend_nan_coerced_to_type_warning (_IS_BOOL );
705+ }
700706 ZVAL_BOOL (op , Z_DVAL_P (op ) ? 1 : 0 );
701707 break ;
702708 case IS_STRING :
@@ -810,6 +816,9 @@ ZEND_API bool ZEND_FASTCALL _try_convert_to_string(zval *op) /* {{{ */
810816
811817static void convert_scalar_to_array (zval * op ) /* {{{ */
812818{
819+ if (UNEXPECTED (Z_TYPE_P (op ) == IS_DOUBLE && zend_isnan (Z_DVAL_P (op )))) {
820+ zend_nan_coerced_to_type_warning (IS_ARRAY );
821+ }
813822 HashTable * ht = zend_new_array (1 );
814823 zend_hash_index_add_new (ht , 0 , op );
815824 ZVAL_ARR (op , ht );
@@ -892,6 +901,11 @@ ZEND_API void ZEND_FASTCALL convert_to_object(zval *op) /* {{{ */
892901 case IS_REFERENCE :
893902 zend_unwrap_reference (op );
894903 goto try_again ;
904+ case IS_DOUBLE :
905+ if (UNEXPECTED (zend_isnan (Z_DVAL_P (op )))) {
906+ zend_nan_coerced_to_type_warning (IS_OBJECT );
907+ }
908+ ZEND_FALLTHROUGH ;
895909 default : {
896910 zval tmp ;
897911 ZVAL_COPY_VALUE (& tmp , op );
@@ -912,6 +926,11 @@ ZEND_API void ZEND_COLD zend_incompatible_string_to_long_error(const zend_string
912926 zend_error (E_DEPRECATED , "Implicit conversion from float-string \"%s\" to int loses precision" , ZSTR_VAL (s ));
913927}
914928
929+ ZEND_API void ZEND_COLD zend_nan_coerced_to_type_warning (uint8_t type )
930+ {
931+ zend_error (E_WARNING , "unexpected NAN value was coerced to %s" , zend_get_type_by_const (type ));
932+ }
933+
915934ZEND_API zend_long ZEND_FASTCALL zval_get_long_func (const zval * op , bool is_strict ) /* {{{ */
916935{
917936try_again :
@@ -2246,6 +2265,8 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
22462265 double str_dval ;
22472266 uint8_t type = is_numeric_string (ZSTR_VAL (str ), ZSTR_LEN (str ), & str_lval , & str_dval , 0 );
22482267
2268+ ZEND_ASSERT (!zend_isnan (dval ));
2269+
22492270 if (type == IS_LONG ) {
22502271 return ZEND_THREEWAY_COMPARE (dval , (double ) str_lval );
22512272 }
@@ -2264,7 +2285,7 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
22642285
22652286ZEND_API int ZEND_FASTCALL zend_compare (zval * op1 , zval * op2 ) /* {{{ */
22662287{
2267- int converted = 0 ;
2288+ bool converted = false ;
22682289 zval op1_copy , op2_copy ;
22692290
22702291 while (1 ) {
@@ -2371,6 +2392,13 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
23712392 }
23722393
23732394 if (!converted ) {
2395+ /* Handle NAN */
2396+ if (
2397+ Z_TYPE_P (op1 ) == IS_DOUBLE && zend_isnan (Z_DVAL_P (op1 ))
2398+ || Z_TYPE_P (op2 ) == IS_DOUBLE && zend_isnan (Z_DVAL_P (op2 ))
2399+ ) {
2400+ return 1 ;
2401+ }
23742402 if (Z_TYPE_P (op1 ) < IS_TRUE ) {
23752403 return zval_is_true (op2 ) ? -1 : 0 ;
23762404 } else if (Z_TYPE_P (op1 ) == IS_TRUE ) {
@@ -2385,7 +2413,7 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
23852413 if (EG (exception )) {
23862414 return 1 ; /* to stop comparison of arrays */
23872415 }
2388- converted = 1 ;
2416+ converted = true ;
23892417 }
23902418 } else if (Z_TYPE_P (op1 )== IS_ARRAY ) {
23912419 return 1 ;
@@ -3543,6 +3571,9 @@ ZEND_API zend_string* ZEND_FASTCALL zend_double_to_str(double num)
35433571 int precision = (int ) EG (precision );
35443572 zend_gcvt (num , precision ? precision : 1 , '.' , 'E' , buf );
35453573 zend_string * str = zend_string_init (buf , strlen (buf ), 0 );
3574+ if (UNEXPECTED (zend_string_equals_literal (str , "NAN" ))) {
3575+ zend_nan_coerced_to_type_warning (IS_STRING );
3576+ }
35463577 GC_ADD_FLAGS (str , IS_STR_VALID_UTF8 );
35473578 return str ;
35483579}
0 commit comments