@@ -426,18 +426,39 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **p
426426}
427427/* }}} */
428428
429- static ZEND_COLD bool zend_null_arg_deprecated (const char * type ) {
429+ static ZEND_COLD bool zend_null_arg_deprecated (const char * fallback_type , uint32_t arg_num ) {
430+ zend_function * func = EG (current_execute_data )-> func ;
431+ ZEND_ASSERT (arg_num > 0 );
432+ uint32_t arg_offset = arg_num - 1 ;
433+ if (arg_offset >= func -> common .num_args ) {
434+ ZEND_ASSERT (func -> common .fn_flags & ZEND_ACC_VARIADIC );
435+ arg_offset = func -> common .num_args ;
436+ }
437+
438+ zend_arg_info * arg_info = & func -> common .arg_info [arg_offset ];
430439 zend_string * func_name = get_active_function_or_method_name ();
431- zend_error (E_DEPRECATED , "%s(): Passing null to parameter of type %s is deprecated" ,
432- ZSTR_VAL (func_name ), type );
440+ const char * arg_name = get_active_function_arg_name (arg_num );
441+
442+ /* If no type is specified in arginfo, use the specified fallback_type determined through
443+ * zend_parse_parameters instead. */
444+ zend_string * type_str = zend_type_to_string (arg_info -> type );
445+ const char * type = type_str ? ZSTR_VAL (type_str ) : fallback_type ;
446+ zend_error (E_DEPRECATED ,
447+ "%s(): Passing null to parameter #%" PRIu32 "%s%s%s of type %s is deprecated" ,
448+ ZSTR_VAL (func_name ), arg_num ,
449+ arg_name ? " ($" : "" , arg_name ? arg_name : "" , arg_name ? ")" : "" ,
450+ type );
433451 zend_string_release (func_name );
452+ if (type_str ) {
453+ zend_string_release (type_str );
454+ }
434455 return !EG (exception );
435456}
436457
437- ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak (zval * arg , bool * dest ) /* {{{ */
458+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak (zval * arg , bool * dest , uint32_t arg_num ) /* {{{ */
438459{
439460 if (EXPECTED (Z_TYPE_P (arg ) <= IS_STRING )) {
440- if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("bool" )) {
461+ if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("bool" , arg_num )) {
441462 return 0 ;
442463 }
443464 * dest = zend_is_true (arg );
@@ -448,16 +469,16 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, bool *dest) /* {
448469}
449470/* }}} */
450471
451- ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow (zval * arg , bool * dest ) /* {{{ */
472+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_slow (zval * arg , bool * dest , uint32_t arg_num ) /* {{{ */
452473{
453474 if (UNEXPECTED (ZEND_ARG_USES_STRICT_TYPES ())) {
454475 return 0 ;
455476 }
456- return zend_parse_arg_bool_weak (arg , dest );
477+ return zend_parse_arg_bool_weak (arg , dest , arg_num );
457478}
458479/* }}} */
459480
460- ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak (zval * arg , zend_long * dest ) /* {{{ */
481+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak (zval * arg , zend_long * dest , uint32_t arg_num ) /* {{{ */
461482{
462483 if (EXPECTED (Z_TYPE_P (arg ) == IS_DOUBLE )) {
463484 if (UNEXPECTED (zend_isnan (Z_DVAL_P (arg )))) {
@@ -490,7 +511,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest)
490511 return 0 ;
491512 }
492513 } else if (EXPECTED (Z_TYPE_P (arg ) < IS_TRUE )) {
493- if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("int" )) {
514+ if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("int" , arg_num )) {
494515 return 0 ;
495516 }
496517 * dest = 0 ;
@@ -503,16 +524,16 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest)
503524}
504525/* }}} */
505526
506- ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow (zval * arg , zend_long * dest ) /* {{{ */
527+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow (zval * arg , zend_long * dest , uint32_t arg_num ) /* {{{ */
507528{
508529 if (UNEXPECTED (ZEND_ARG_USES_STRICT_TYPES ())) {
509530 return 0 ;
510531 }
511- return zend_parse_arg_long_weak (arg , dest );
532+ return zend_parse_arg_long_weak (arg , dest , arg_num );
512533}
513534/* }}} */
514535
515- ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak (zval * arg , double * dest ) /* {{{ */
536+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak (zval * arg , double * dest , uint32_t arg_num ) /* {{{ */
516537{
517538 if (EXPECTED (Z_TYPE_P (arg ) == IS_LONG )) {
518539 * dest = (double )Z_LVAL_P (arg );
@@ -531,7 +552,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest)
531552 return 0 ;
532553 }
533554 } else if (EXPECTED (Z_TYPE_P (arg ) < IS_TRUE )) {
534- if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("float" )) {
555+ if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("float" , arg_num )) {
535556 return 0 ;
536557 }
537558 * dest = 0.0 ;
@@ -544,19 +565,19 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest)
544565}
545566/* }}} */
546567
547- ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow (zval * arg , double * dest ) /* {{{ */
568+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow (zval * arg , double * dest , uint32_t arg_num ) /* {{{ */
548569{
549570 if (EXPECTED (Z_TYPE_P (arg ) == IS_LONG )) {
550571 /* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */
551572 * dest = (double )Z_LVAL_P (arg );
552573 } else if (UNEXPECTED (ZEND_ARG_USES_STRICT_TYPES ())) {
553574 return 0 ;
554575 }
555- return zend_parse_arg_double_weak (arg , dest );
576+ return zend_parse_arg_double_weak (arg , dest , arg_num );
556577}
557578/* }}} */
558579
559- ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow (zval * arg , zval * * dest ) /* {{{ */
580+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow (zval * arg , zval * * dest , uint32_t arg_num ) /* {{{ */
560581{
561582 if (UNEXPECTED (ZEND_ARG_USES_STRICT_TYPES ())) {
562583 return 0 ;
@@ -575,6 +596,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest) /
575596 }
576597 zend_string_release (str );
577598 } else if (Z_TYPE_P (arg ) < IS_TRUE ) {
599+ if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("int|float" , arg_num )) {
600+ return 0 ;
601+ }
578602 ZVAL_LONG (arg , 0 );
579603 } else if (Z_TYPE_P (arg ) == IS_TRUE ) {
580604 ZVAL_LONG (arg , 1 );
@@ -586,10 +610,10 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest) /
586610}
587611/* }}} */
588612
589- ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak (zval * arg , zend_string * * dest ) /* {{{ */
613+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak (zval * arg , zend_string * * dest , uint32_t arg_num ) /* {{{ */
590614{
591615 if (EXPECTED (Z_TYPE_P (arg ) < IS_STRING )) {
592- if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("string" )) {
616+ if (UNEXPECTED (Z_TYPE_P (arg ) == IS_NULL ) && !zend_null_arg_deprecated ("string" , arg_num )) {
593617 return 0 ;
594618 }
595619 convert_to_string (arg );
@@ -611,24 +635,24 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **des
611635}
612636/* }}} */
613637
614- ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow (zval * arg , zend_string * * dest ) /* {{{ */
638+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow (zval * arg , zend_string * * dest , uint32_t arg_num ) /* {{{ */
615639{
616640 if (UNEXPECTED (ZEND_ARG_USES_STRICT_TYPES ())) {
617641 return 0 ;
618642 }
619- return zend_parse_arg_str_weak (arg , dest );
643+ return zend_parse_arg_str_weak (arg , dest , arg_num );
620644}
621645/* }}} */
622646
623- ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow (zval * arg , zend_string * * dest_str , zend_long * dest_long ) /* {{{ */
647+ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow (zval * arg , zend_string * * dest_str , zend_long * dest_long , uint32_t arg_num ) /* {{{ */
624648{
625649 if (UNEXPECTED (ZEND_ARG_USES_STRICT_TYPES ())) {
626650 return 0 ;
627651 }
628- if (zend_parse_arg_long_weak (arg , dest_long )) {
652+ if (zend_parse_arg_long_weak (arg , dest_long , arg_num )) {
629653 * dest_str = NULL ;
630654 return 1 ;
631- } else if (zend_parse_arg_str_weak (arg , dest_str )) {
655+ } else if (zend_parse_arg_str_weak (arg , dest_str , arg_num )) {
632656 * dest_long = 0 ;
633657 return 1 ;
634658 } else {
@@ -637,7 +661,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_stri
637661}
638662/* }}} */
639663
640- static const char * zend_parse_arg_impl (zval * arg , va_list * va , const char * * spec , char * * error ) /* {{{ */
664+ static const char * zend_parse_arg_impl (zval * arg , va_list * va , const char * * spec , char * * error , uint32_t arg_num ) /* {{{ */
641665{
642666 const char * spec_walk = * spec ;
643667 char c = * spec_walk ++ ;
@@ -670,7 +694,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
670694 is_null = va_arg (* va , bool * );
671695 }
672696
673- if (!zend_parse_arg_long (arg , p , is_null , check_null )) {
697+ if (!zend_parse_arg_long (arg , p , is_null , check_null , arg_num )) {
674698 return check_null ? "?int" : "int" ;
675699 }
676700 }
@@ -685,7 +709,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
685709 is_null = va_arg (* va , bool * );
686710 }
687711
688- if (!zend_parse_arg_double (arg , p , is_null , check_null )) {
712+ if (!zend_parse_arg_double (arg , p , is_null , check_null , arg_num )) {
689713 return check_null ? "?float" : "float" ;
690714 }
691715 }
@@ -695,7 +719,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
695719 {
696720 zval * * p = va_arg (* va , zval * * );
697721
698- if (!zend_parse_arg_number (arg , p , check_null )) {
722+ if (!zend_parse_arg_number (arg , p , check_null , arg_num )) {
699723 return check_null ? "int|float|null" : "int|float" ;
700724 }
701725 }
@@ -705,7 +729,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
705729 {
706730 char * * p = va_arg (* va , char * * );
707731 size_t * pl = va_arg (* va , size_t * );
708- if (!zend_parse_arg_string (arg , p , pl , check_null )) {
732+ if (!zend_parse_arg_string (arg , p , pl , check_null , arg_num )) {
709733 return check_null ? "?string" : "string" ;
710734 }
711735 }
@@ -715,7 +739,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
715739 {
716740 char * * p = va_arg (* va , char * * );
717741 size_t * pl = va_arg (* va , size_t * );
718- if (!zend_parse_arg_path (arg , p , pl , check_null )) {
742+ if (!zend_parse_arg_path (arg , p , pl , check_null , arg_num )) {
719743 if (Z_TYPE_P (arg ) == IS_STRING ) {
720744 zend_spprintf (error , 0 , "must not contain any null bytes" );
721745 return "" ;
@@ -729,7 +753,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
729753 case 'P' :
730754 {
731755 zend_string * * str = va_arg (* va , zend_string * * );
732- if (!zend_parse_arg_path_str (arg , str , check_null )) {
756+ if (!zend_parse_arg_path_str (arg , str , check_null , arg_num )) {
733757 if (Z_TYPE_P (arg ) == IS_STRING ) {
734758 zend_spprintf (error , 0 , "must not contain any null bytes" );
735759 return "" ;
@@ -743,7 +767,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
743767 case 'S' :
744768 {
745769 zend_string * * str = va_arg (* va , zend_string * * );
746- if (!zend_parse_arg_str (arg , str , check_null )) {
770+ if (!zend_parse_arg_str (arg , str , check_null , arg_num )) {
747771 return check_null ? "?string" : "string" ;
748772 }
749773 }
@@ -758,7 +782,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
758782 is_null = va_arg (* va , bool * );
759783 }
760784
761- if (!zend_parse_arg_bool (arg , p , is_null , check_null )) {
785+ if (!zend_parse_arg_bool (arg , p , is_null , check_null , arg_num )) {
762786 return check_null ? "?bool" : "bool" ;
763787 }
764788 }
@@ -919,7 +943,7 @@ static zend_result zend_parse_arg(uint32_t arg_num, zval *arg, va_list *va, cons
919943 const char * expected_type = NULL ;
920944 char * error = NULL ;
921945
922- expected_type = zend_parse_arg_impl (arg , va , spec , & error );
946+ expected_type = zend_parse_arg_impl (arg , va , spec , & error , arg_num );
923947 if (expected_type ) {
924948 if (EG (exception )) {
925949 return FAILURE ;
0 commit comments