@@ -587,7 +587,7 @@ typedef enum {
587
587
ZEND_INI_PARSE_QUANTITY_UNSIGNED ,
588
588
} zend_ini_parse_quantity_signed_result_t ;
589
589
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 ) {
591
591
const char * digits_consumed = digits ;
592
592
/* Ignore leading whitespace. */
593
593
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
598
598
if (digits_consumed [0 ] == '0' && !isdigit (digits_consumed [1 ])) {
599
599
/* Value is just 0 */
600
600
if ((digits_consumed + 1 ) == str_end ) {
601
- return digits ;
601
+ return digits_consumed ;
602
602
}
603
603
604
604
switch (digits_consumed [1 ]) {
605
605
case 'x' :
606
606
case 'X' :
607
607
case 'o' :
608
608
case 'O' :
609
+ digits_consumed += 2 ;
610
+ break ;
609
611
case 'b' :
610
612
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
+ }
612
617
break ;
613
618
}
614
619
}
@@ -696,19 +701,8 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
696
701
return 0 ;
697
702
}
698
703
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 ))) {
712
706
/* Escape the string to avoid null bytes and to make non-printable chars
713
707
* visible */
714
708
smart_str_append_escaped (& invalid , ZSTR_VAL (value ), ZSTR_LEN (value ));
0 commit comments