@@ -587,7 +587,7 @@ typedef enum {
587587 ZEND_INI_PARSE_QUANTITY_UNSIGNED ,
588588} zend_ini_parse_quantity_signed_result_t ;
589589
590- static const char * zend_ini_consume_quantity_prefix (const char * const digits , const char * const str_end ) {
590+ static const char * zend_ini_consume_quantity_prefix (const char * const digits , const char * const str_end , int base ) {
591591 const char * digits_consumed = digits ;
592592 /* Ignore leading whitespace. */
593593 while (digits_consumed < str_end && zend_is_whitespace (* digits_consumed )) {++ digits_consumed ;}
@@ -598,17 +598,22 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
598598 if (digits_consumed [0 ] == '0' && !isdigit (digits_consumed [1 ])) {
599599 /* Value is just 0 */
600600 if ((digits_consumed + 1 ) == str_end ) {
601- return digits ;
601+ return digits_consumed ;
602602 }
603603
604604 switch (digits_consumed [1 ]) {
605605 case 'x' :
606606 case 'X' :
607607 case 'o' :
608608 case 'O' :
609+ digits_consumed += 2 ;
610+ break ;
609611 case 'b' :
610612 case 'B' :
611- digits_consumed += 2 ;
613+ if (base != 16 ) {
614+ /* 0b or 0B is valid in base 16, but not in the other supported bases. */
615+ digits_consumed += 2 ;
616+ }
612617 break ;
613618 }
614619 }
@@ -696,19 +701,8 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
696701 return 0 ;
697702 }
698703 digits += 2 ;
699- if (UNEXPECTED (digits == str_end )) {
700- /* Escape the string to avoid null bytes and to make non-printable chars
701- * visible */
702- smart_str_append_escaped (& invalid , ZSTR_VAL (value ), ZSTR_LEN (value ));
703- smart_str_0 (& invalid );
704-
705- * errstr = zend_strpprintf (0 , "Invalid quantity \"%s\": no digits after base prefix, interpreting as \"0\" for backwards compatibility" ,
706- ZSTR_VAL (invalid .s ));
707-
708- smart_str_free (& invalid );
709- return 0 ;
710- }
711- if (UNEXPECTED (digits != zend_ini_consume_quantity_prefix (digits , str_end ))) {
704+ /* STRTOULL may silently ignore a prefix of whitespace, sign, and base prefix, which would be invalid at this position */
705+ if (UNEXPECTED (digits == str_end || digits != zend_ini_consume_quantity_prefix (digits , str_end , base ))) {
712706 /* Escape the string to avoid null bytes and to make non-printable chars
713707 * visible */
714708 smart_str_append_escaped (& invalid , ZSTR_VAL (value ), ZSTR_LEN (value ));
0 commit comments