Skip to content

Commit c559710

Browse files
committed
Null safety
1 parent a850666 commit c559710

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
Test parsing of quantities with null byte
3+
--FILE--
4+
<?php
5+
6+
var_dump(zend_test_zend_ini_parse_quantity(" 123\x00K"));
7+
var_dump(zend_test_zend_ini_parse_quantity("\x00 123K"));
8+
var_dump(zend_test_zend_ini_parse_quantity(" \x00123K"));
9+
var_dump(zend_test_zend_ini_parse_quantity(" 123\x00K"));
10+
var_dump(zend_test_zend_ini_parse_quantity(" 123K\x00"));
11+
var_dump(zend_test_zend_ini_parse_quantity(" 123\x00"));
12+
13+
--EXPECTF--
14+
Warning: Invalid quantity ' 123\x00K', interpreting as ' 123K' for backwards compatibility in %s on line %d
15+
int(125952)
16+
17+
Warning: Invalid quantity '\x00 123K': no valid leading digits, interpreting as '0' for backwards compatibility in %s on line %d
18+
int(0)
19+
20+
Warning: Invalid quantity ' \x00123K': no valid leading digits, interpreting as '0' for backwards compatibility in %s on line %d
21+
int(0)
22+
23+
Warning: Invalid quantity ' 123\x00K', interpreting as ' 123K' for backwards compatibility in %s on line %d
24+
int(125952)
25+
26+
Warning: Invalid quantity ' 123K\x00': unknown multipler '\x00', interpreting as ' 123' for backwards compatibility in %s on line %d
27+
int(123)
28+
29+
Warning: Invalid quantity ' 123\x00': unknown multipler '\x00', interpreting as ' 123' for backwards compatibility in %s on line %d
30+
int(123)

Zend/zend_ini.c

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "zend_operators.h"
2525
#include "zend_strtod.h"
2626
#include "zend_modules.h"
27+
#include "zend_smart_str.h"
2728

2829
static HashTable *registered_zend_ini_directives;
2930

@@ -545,6 +546,9 @@ ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **err
545546
char *digits_end = NULL;
546547
char *str = ZSTR_VAL(value);
547548
size_t str_len = ZSTR_LEN(value);
549+
smart_str invalid = {0};
550+
smart_str interpreted = {0};
551+
smart_str chr = {0};
548552

549553
/* Ignore trailing whitespace */
550554
while (str_len && zend_is_whitespace(str[str_len-1])) --str_len;
@@ -562,16 +566,21 @@ ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **err
562566
zend_ulong retval = (zend_ulong) ZEND_STRTOL(str, &digits_end, 0);
563567

564568
if (digits_end == str) {
565-
*errstr = zend_strpprintf(0, "Invalid quantity '%.*s': no valid leading digits, interpreting as '0' for backwards compatibility",
566-
(int)str_len, str);
569+
smart_str_append_escaped(&invalid, str, str_len);
570+
smart_str_0(&invalid);
571+
572+
*errstr = zend_strpprintf(0, "Invalid quantity '%s': no valid leading digits, interpreting as '0' for backwards compatibility",
573+
ZSTR_VAL(invalid.s));
574+
575+
smart_str_free(&invalid);
567576
return 0;
568577
}
569578

570579
/* Allow for whitespace between integer portion and any suffix character */
571-
while (zend_is_whitespace(*digits_end)) ++digits_end;
580+
while (digits_end < &str[str_len] && zend_is_whitespace(*digits_end)) ++digits_end;
572581

573582
/* No exponent suffix. */
574-
if (!*digits_end) {
583+
if (digits_end == &str[str_len]) {
575584
*errstr = NULL;
576585
return retval;
577586
}
@@ -590,18 +599,42 @@ ZEND_API zend_long zend_ini_parse_quantity(zend_string *value, zend_string **err
590599
case 'K':
591600
retval *= 1024;
592601
break;
593-
default:
594-
/* Unknown suffix */
595-
*errstr = zend_strpprintf(0, "Invalid quantity '%.*s': unknown multipler '%c', interpreting as '%.*s' for backwards compatibility",
596-
(int)str_len, str, str[str_len-1], (int)(digits_end - str), str);
597-
return retval;
602+
default:
603+
/* Unknown suffix */
604+
smart_str_append_escaped(&invalid, str, str_len);
605+
smart_str_0(&invalid);
606+
smart_str_append_escaped(&interpreted, str, digits_end - str);
607+
smart_str_0(&interpreted);
608+
smart_str_append_escaped(&chr, &str[str_len-1], 1);
609+
smart_str_0(&chr);
610+
611+
*errstr = zend_strpprintf(0, "Invalid quantity '%s': unknown multipler '%s', interpreting as '%s' for backwards compatibility",
612+
ZSTR_VAL(invalid.s), ZSTR_VAL(chr.s), ZSTR_VAL(interpreted.s));
613+
614+
smart_str_free(&invalid);
615+
smart_str_free(&interpreted);
616+
smart_str_free(&chr);
617+
618+
return retval;
598619
}
599620
}
600621

601622
if (digits_end < &str[str_len-1]) {
602623
/* More than one character in suffix */
603-
*errstr = zend_strpprintf(0, "Invalid quantity '%.*s', interpreting as '%.*s%c' for backwards compatibility",
604-
(int)str_len, str, (int)(digits_end - str), str, str[str_len-1]);
624+
smart_str_append_escaped(&invalid, str, str_len);
625+
smart_str_0(&invalid);
626+
smart_str_append_escaped(&interpreted, str, digits_end - str);
627+
smart_str_0(&interpreted);
628+
smart_str_append_escaped(&chr, &str[str_len-1], 1);
629+
smart_str_0(&chr);
630+
631+
*errstr = zend_strpprintf(0, "Invalid quantity '%s', interpreting as '%s%s' for backwards compatibility",
632+
ZSTR_VAL(invalid.s), ZSTR_VAL(interpreted.s), ZSTR_VAL(chr.s));
633+
634+
smart_str_free(&invalid);
635+
smart_str_free(&interpreted);
636+
smart_str_free(&chr);
637+
605638
return (zend_long) retval;
606639
}
607640

0 commit comments

Comments
 (0)