Skip to content

Commit 2a78523

Browse files
committed
Make null byte error a ValueError
1 parent b4ee5df commit 2a78523

40 files changed

+172
-158
lines changed

Zend/zend_API.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,12 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t n
254254
return;
255255
}
256256

257+
if ((expected_type == Z_EXPECTED_PATH || expected_type == Z_EXPECTED_PATH_OR_NULL)
258+
&& Z_TYPE_P(arg) == IS_STRING) {
259+
zend_argument_value_error(num, "must not contain any null bytes");
260+
return;
261+
}
262+
257263
zend_argument_type_error(num, "must be %s, %s given", expected_error[expected_type], zend_zval_type_name(arg));
258264
}
259265
/* }}} */
@@ -668,10 +674,12 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
668674
char **p = va_arg(*va, char **);
669675
size_t *pl = va_arg(*va, size_t *);
670676
if (!zend_parse_arg_path(arg, p, pl, check_null)) {
671-
zend_spprintf(error, 0, "a valid path%s, %s given",
672-
check_null ? " or null" : "", zend_zval_type_name(arg)
673-
);
674-
return "";
677+
if (Z_TYPE_P(arg) == IS_STRING) {
678+
zend_spprintf(error, 0, "must not contain any null bytes");
679+
return "";
680+
} else {
681+
return check_null ? "?string" : "string";
682+
}
675683
}
676684
}
677685
break;
@@ -680,10 +688,12 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
680688
{
681689
zend_string **str = va_arg(*va, zend_string **);
682690
if (!zend_parse_arg_path_str(arg, str, check_null)) {
683-
zend_spprintf(error, 0, "a valid path%s, %s given",
684-
check_null ? " or null" : "", zend_zval_type_name(arg)
685-
);
686-
return "";
691+
if (Z_TYPE_P(arg) == IS_STRING) {
692+
zend_spprintf(error, 0, "must not contain any null bytes");
693+
return "";
694+
} else {
695+
return check_null ? "?string" : "string";
696+
}
687697
}
688698
}
689699
break;
@@ -762,7 +772,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
762772
if (!zend_parse_arg_object(arg, p, ce, check_null)) {
763773
if (ce) {
764774
if (check_null) {
765-
zend_spprintf(error, 0, "of type ?%s, %s given", ZSTR_VAL(ce->name), zend_zval_type_name(arg));
775+
zend_spprintf(error, 0, "must be of type ?%s, %s given", ZSTR_VAL(ce->name), zend_zval_type_name(arg));
766776
return "";
767777
} else {
768778
return ZSTR_VAL(ce->name);
@@ -795,14 +805,14 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
795805
}
796806
if (ce_base) {
797807
if ((!*pce || !instanceof_function(*pce, ce_base))) {
798-
zend_spprintf(error, 0, "a class name derived from %s%s, %s given",
808+
zend_spprintf(error, 0, "must be a class name derived from %s%s, %s given",
799809
ZSTR_VAL(ce_base->name), check_null ? " or null" : "", Z_STRVAL_P(arg));
800810
*pce = NULL;
801811
return "";
802812
}
803813
}
804814
if (!*pce) {
805-
zend_spprintf(error, 0, "a valid class name%s, %s given",
815+
zend_spprintf(error, 0, "must be a valid class name%s, %s given",
806816
check_null ? " or null" : "", Z_STRVAL_P(arg));
807817
return "";
808818
}
@@ -833,7 +843,7 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec
833843
}
834844

835845
if (is_callable_error) {
836-
zend_spprintf(error, 0, "a valid callback%s, %s", check_null ? " or null" : "", is_callable_error);
846+
zend_spprintf(error, 0, "must be a valid callback%s, %s", check_null ? " or null" : "", is_callable_error);
837847
efree(is_callable_error);
838848
return "";
839849
} else {
@@ -874,7 +884,11 @@ static zend_result zend_parse_arg(uint32_t arg_num, zval *arg, va_list *va, cons
874884
}
875885
if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) {
876886
if (error) {
877-
zend_argument_type_error(arg_num, "must be %s", error);
887+
if (strcmp(error, "must not contain any null bytes") == 0) {
888+
zend_argument_value_error(arg_num, "%s", error);
889+
} else {
890+
zend_argument_type_error(arg_num, "%s", error);
891+
}
878892
efree(error);
879893
} else {
880894
zend_argument_type_error(arg_num, "must be of type %s, %s given", expected_type, zend_zval_type_name(arg));

Zend/zend_API.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,8 +1215,8 @@ static zend_always_inline zval *zend_try_array_init(zval *zv)
12151215
_(Z_EXPECTED_FUNC_OR_NULL, "a valid callback or null") \
12161216
_(Z_EXPECTED_RESOURCE, "of type resource") \
12171217
_(Z_EXPECTED_RESOURCE_OR_NULL, "of type resource or null") \
1218-
_(Z_EXPECTED_PATH, "a valid path") \
1219-
_(Z_EXPECTED_PATH_OR_NULL, "a valid path or null") \
1218+
_(Z_EXPECTED_PATH, "of type string") \
1219+
_(Z_EXPECTED_PATH_OR_NULL, "of type ?string") \
12201220
_(Z_EXPECTED_OBJECT, "of type object") \
12211221
_(Z_EXPECTED_OBJECT_OR_NULL, "of type ?object") \
12221222
_(Z_EXPECTED_DOUBLE, "of type float") \

ext/fileinfo/tests/finfo_open_001.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ finfo_open(): Testing magic_file names
77

88
try {
99
var_dump(finfo_open(FILEINFO_MIME, "\0"));
10-
} catch (TypeError $e) {
10+
} catch (ValueError $e) {
1111
echo $e->getMessage(), "\n";
1212
}
1313

@@ -19,7 +19,7 @@ var_dump(finfo_open(FILEINFO_MIME, '/foo/bar/inexistent'));
1919

2020
?>
2121
--EXPECTF--
22-
finfo_open(): Argument #2 ($arg) must be a valid path, string given
22+
finfo_open(): Argument #2 ($arg) must not contain any null bytes
2323
resource(%d) of type (file_info)
2424
resource(%d) of type (file_info)
2525

ext/gd/tests/imagegd2_nullbyte_injection.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ Testing null byte injection in imagegd2
99
$image = imagecreate(1,1);// 1px image
1010
try {
1111
imagegd($image, "./foo\0bar");
12-
} catch (TypeError $e) {
12+
} catch (ValueError $e) {
1313
echo $e->getMessage(), "\n";
1414
}
1515
?>
1616
--EXPECT--
17-
imagegd(): Argument #2 ($to) must be a valid path, string given
17+
imagegd(): Argument #2 ($to) must not contain any null bytes

ext/gd/tests/imagegd_nullbyte_injection.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ Testing null byte injection in imagegd
99
$image = imagecreate(1,1);// 1px image
1010
try {
1111
imagegd($image, "./foo\0bar");
12-
} catch (TypeError $e) {
12+
} catch (ValueError $e) {
1313
echo $e->getMessage(), "\n";
1414
}
1515
?>
1616
--EXPECT--
17-
imagegd(): Argument #2 ($to) must be a valid path, string given
17+
imagegd(): Argument #2 ($to) must not contain any null bytes

ext/gd/tests/imagexbm_nullbyte_injection.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ if(!extension_loaded('gd')) die('skip gd extension not available');
99
$image = imagecreate(1,1);// 1px image
1010
try {
1111
imagexbm($image, "./foo\0bar");
12-
} catch (TypeError $e) {
12+
} catch (ValueError $e) {
1313
echo $e->getMessage(), "\n";
1414
}
1515
?>
1616
--EXPECT--
17-
imagexbm(): Argument #2 ($filename) must be a valid path or null, string given
17+
imagexbm(): Argument #2 ($filename) must not contain any null bytes

ext/phar/tests/badparameters.phpt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,13 @@ try {
229229
?>
230230
--EXPECTF--
231231
Phar::mungServer(): Argument #1 ($munglist) must be of type array, string given
232-
Phar::createDefaultStub(): Argument #1 ($index) must be a valid path or null, array given
233-
Phar::loadPhar(): Argument #1 ($filename) must be a valid path, array given
232+
Phar::createDefaultStub(): Argument #1 ($index) must be of type ?string, array given
233+
Phar::loadPhar(): Argument #1 ($filename) must be of type string, array given
234234
Phar::canCompress(): Argument #1 ($method) must be of type int, string given
235-
Phar::__construct(): Argument #1 ($filename) must be a valid path, array given
235+
Phar::__construct(): Argument #1 ($filename) must be of type string, array given
236236
Phar::convertToExecutable(): Argument #1 ($format) must be of type int, array given
237237
Phar::convertToData(): Argument #1 ($format) must be of type int, array given
238-
PharData::delete(): Argument #1 ($entry) must be a valid path, array given
238+
PharData::delete(): Argument #1 ($entry) must be of type string, array given
239239
Cannot write out phar archive, phar is read-only
240240
Entry oops does not exist and cannot be deleted
241241
%sfrontcontroller10.phar
@@ -255,13 +255,13 @@ Phar::compressFiles(): Argument #1 ($compression_type) must be of type int, arra
255255
Phar is readonly, cannot change compression
256256
Phar::copy() expects exactly 2 parameters, 1 given
257257
Cannot copy "a" to "b", phar is read-only
258-
Phar::offsetExists(): Argument #1 ($entry) must be a valid path, array given
259-
Phar::offsetGet(): Argument #1 ($entry) must be a valid path, array given
258+
Phar::offsetExists(): Argument #1 ($entry) must be of type string, array given
259+
Phar::offsetGet(): Argument #1 ($entry) must be of type string, array given
260260
Phar::offsetSet() expects exactly 2 parameters, 1 given
261-
PharData::offsetUnset(): Argument #1 ($entry) must be a valid path, array given
261+
PharData::offsetUnset(): Argument #1 ($entry) must be of type string, array given
262262
Write operations disabled by the php.ini setting phar.readonly
263-
Phar::addEmptyDir(): Argument #1 ($dirname) must be a valid path, array given
264-
Phar::addFile(): Argument #1 ($filename) must be a valid path, array given
263+
Phar::addEmptyDir(): Argument #1 ($dirname) must be of type string, array given
264+
Phar::addFile(): Argument #1 ($filename) must be of type string, array given
265265
Phar::addFromString() expects exactly 2 parameters, 1 given
266266
Write operations disabled by the php.ini setting phar.readonly
267267
Phar::setMetadata() expects exactly 1 parameter, 2 given

ext/phar/tests/bug64931/bug64931.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ try {
3838

3939
try {
4040
$phar->addFromString(".phar\0", "gotcha");
41-
} catch (TypeError $e) {
41+
} catch (ValueError $e) {
4242
echo "CAUGHT: ". $e->getMessage() ."\n";
4343
}
4444

@@ -53,4 +53,4 @@ CAUGHT: Cannot create any files in magic ".phar" directory
5353
CAUGHT: Cannot create any files in magic ".phar" directory
5454
CAUGHT: Cannot create any files in magic ".phar" directory
5555
CAUGHT: Cannot create any files in magic ".phar" directory
56-
CAUGHT: Phar::addFromString(): Argument #1 ($localname) must be a valid path, string given
56+
CAUGHT: Phar::addFromString(): Argument #1 ($localname) must not contain any null bytes

ext/phar/tests/create_path_error.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ foreach($checks as $check)
5353
{
5454
$phar[$check] = 'error';
5555
}
56-
catch (TypeError $e)
56+
catch (ValueError $e)
5757
{
5858
echo 'Exception: ' . $e->getMessage() . "\n";
5959
}
@@ -78,4 +78,4 @@ string(5) "query"
7878
11:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character
7979
12:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character
8080
13:Error: file_put_contents(phar://%s): Failed to open stream: phar error: invalid path "%s" contains illegal character
81-
Exception: Phar::offsetSet(): Argument #1 ($entry) must be a valid path, string given
81+
Exception: Phar::offsetSet(): Argument #1 ($entry) must not contain any null bytes

ext/phar/tests/fgc_edgecases.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ include $pname . '/foo/hi';
5252
<?php unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
5353
<?php unlink(__DIR__ . '/fgc_edgecases.txt'); ?>
5454
--EXPECTF--
55-
file_get_contents(): Argument #1 ($filename) must be a valid path, array given
55+
file_get_contents(): Argument #1 ($filename) must be of type string, array given
5656
blah
5757
<?php
5858
echo file_get_contents("foo/" . basename(__FILE__));

ext/phar/tests/fopen_edgecases2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ include $pname . '/foo/hi';
3737
<?php unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
3838
<?php unlink(__DIR__ . '/fopen_edgecases2.txt'); ?>
3939
--EXPECTF--
40-
fopen(): Argument #1 ($filename) must be a valid path, array given
40+
fopen(): Argument #1 ($filename) must be of type string, array given
4141
blah
4242
test
4343

ext/phar/tests/opendir_edgecases.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ include $pname . '/foo';
5555
<?php unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
5656
<?php rmdir(__DIR__ . '/opendir_edgecases');
5757
--EXPECTF--
58-
opendir(): Argument #1 ($path) must be a valid path, array given
58+
opendir(): Argument #1 ($path) must be of type string, array given
5959
.
6060
..
6161
foo

ext/phar/tests/phar_extract.phpt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,18 @@ $e = __DIR__ . '/extract1-2/';
131131
@rmdir($e);
132132
?>
133133
--EXPECTF--
134-
%sextract%cfile1.txt
135-
%sextract%cfile2.txt
136-
%sextract%cone
137-
%sextract%csubdir
138-
%sextract%csubdir%cectory
139-
%sextract%csubdir%cectory%cfile.txt
134+
/home/nikic/php/php-src/ext/phar/tests/extract/file1.txt
135+
/home/nikic/php/php-src/ext/phar/tests/extract/file2.txt
136+
/home/nikic/php/php-src/ext/phar/tests/extract/one
137+
/home/nikic/php/php-src/ext/phar/tests/extract/subdir
138+
/home/nikic/php/php-src/ext/phar/tests/extract/subdir/ectory
139+
/home/nikic/php/php-src/ext/phar/tests/extract/subdir/ectory/file.txt
140140
string(2) "hi"
141141
string(3) "hi3"
142142
string(3) "hi2"
143143
bool(false)
144144
Phar::extractTo(): Argument #2 ($files) must be of type array|string|null, stdClass given
145-
Phar::extractTo(): Argument #1 ($pathto) must be a valid path, array given
145+
Phar::extractTo(): Argument #1 ($pathto) must be of type string, array given
146146
Invalid argument, extraction path must be non-zero length
147147
Unable to use path "%soops" for extraction, it is a file, must be a directory
148148
Invalid argument, array of filenames to extract contains non-string value

ext/phar/tests/phar_unlinkarchive.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ __HALT_COMPILER();
9292
Unknown phar archive ""
9393
Unknown phar archive "%sphar_unlinkarchive.phar"
9494
Unknown phar archive "%sphar_unlinkarchive.phar.tar": internal corruption of phar "%sphar_unlinkarchive.phar.tar" (truncated entry)
95-
Phar::unlinkArchive(): Argument #1 ($archive) must be a valid path, array given
95+
Phar::unlinkArchive(): Argument #1 ($archive) must be of type string, array given
9696
bool(false)
9797
string(48) "<?php echo "first stub\n"; __HALT_COMPILER(); ?>"
9898
phar archive "%sphar_unlinkarchive.phar" has open file handles or objects. fclose() all file handles, and unset() all objects prior to calling unlinkArchive()

ext/phar/tests/pharfileinfo_construct.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ echo $e->getMessage() . "\n";
4949
<?php unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar'); ?>
5050
--EXPECTF--
5151
Cannot open phar file 'phar://%spharfileinfo_construct.phar/oops': internal corruption of phar "%spharfileinfo_construct.phar" (truncated entry)
52-
PharFileInfo::__construct(): Argument #1 ($filename) must be a valid path, array given
52+
PharFileInfo::__construct(): Argument #1 ($filename) must be of type string, array given
5353
Cannot access phar file entry '%s' in archive '%s'
5454
Cannot call constructor twice
5555
'%s' is not a valid phar archive URL (must have at least phar://filename.phar)

ext/spl/tests/bug54291.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ $dir = new DirectoryIterator("\x00/abc");
66
$dir->isFile();
77
?>
88
--EXPECTF--
9-
Fatal error: Uncaught TypeError: DirectoryIterator::__construct(): Argument #1 ($path) must be a valid path, string given in %s:%d
9+
Fatal error: Uncaught ValueError: DirectoryIterator::__construct(): Argument #1 ($path) must not contain any null bytes in %s:%d
1010
Stack trace:
1111
#0 %s(%d): DirectoryIterator->__construct('\x00/abc')
1212
#1 {main}

ext/spl/tests/bug77431.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Bug #77431 (SplFileInfo::__construct() accepts NUL bytes)
55
new SplFileInfo("bad\0good");
66
?>
77
--EXPECTF--
8-
Fatal error: Uncaught TypeError: SplFileInfo::__construct(): Argument #1 ($file_name) must be a valid path, string given in %s:%d
8+
Fatal error: Uncaught ValueError: SplFileInfo::__construct(): Argument #1 ($file_name) must not contain any null bytes in %s:%d
99
Stack trace:
1010
#0 %s(%d): SplFileInfo->__construct('bad\x00good')
1111
#1 {main}

ext/spl/tests/bug78863.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ foreach ($it as $fileinfo) {
1616
}
1717
?>
1818
--EXPECTF--
19-
Fatal error: Uncaught TypeError: DirectoryIterator::__construct(): Argument #1 ($path) must be a valid path, string given in %s:%d
19+
Fatal error: Uncaught ValueError: DirectoryIterator::__construct(): Argument #1 ($path) must not contain any null bytes in %s:%d
2020
Stack trace:
2121
#0 %s(%d): DirectoryIterator->__construct('%s')
2222
#1 {main}

ext/standard/tests/file/bug39863.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ $filename = __FILE__ . chr(0). ".ridiculous";
99

1010
try {
1111
var_dump(file_exists($filename));
12-
} catch (TypeError $e) {
12+
} catch (ValueError $e) {
1313
echo $e->getMessage(), "\n";
1414
}
1515
?>
1616
--EXPECT--
17-
file_exists(): Argument #1 ($filename) must be a valid path, string given
17+
file_exists(): Argument #1 ($filename) must not contain any null bytes

ext/standard/tests/file/disk_free_space_variation.phpt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ foreach($dirs_arr as $dir1) {
4343
echo "\n-- Iteration $count --\n";
4444
try {
4545
var_dump( disk_free_space( $dir1 ) );
46-
} catch (TypeError $e) {
46+
} catch (Error $e) {
4747
echo $e->getMessage(), "\n";
4848
}
4949
try {
5050
var_dump( diskfreespace( $dir1 ) );
51-
} catch (TypeError $e) {
51+
} catch (Error $e) {
5252
echo $e->getMessage(), "\n";
5353
}
5454
$count++;
@@ -103,19 +103,19 @@ float(%f)
103103
float(%f)
104104

105105
-- Iteration 9 --
106-
disk_free_space(): Argument #1 ($directory) must be a valid path, string given
107-
diskfreespace(): Argument #1 ($directory) must be a valid path, string given
106+
disk_free_space(): Argument #1 ($directory) must not contain any null bytes
107+
diskfreespace(): Argument #1 ($directory) must not contain any null bytes
108108

109109
-- Iteration 10 --
110-
disk_free_space(): Argument #1 ($directory) must be a valid path, string given
111-
diskfreespace(): Argument #1 ($directory) must be a valid path, string given
110+
disk_free_space(): Argument #1 ($directory) must not contain any null bytes
111+
diskfreespace(): Argument #1 ($directory) must not contain any null bytes
112112

113113
-- Iteration 11 --
114-
disk_free_space(): Argument #1 ($directory) must be a valid path, string given
115-
diskfreespace(): Argument #1 ($directory) must be a valid path, string given
114+
disk_free_space(): Argument #1 ($directory) must not contain any null bytes
115+
diskfreespace(): Argument #1 ($directory) must not contain any null bytes
116116

117117
-- Iteration 12 --
118-
disk_free_space(): Argument #1 ($directory) must be a valid path, string given
119-
diskfreespace(): Argument #1 ($directory) must be a valid path, string given
118+
disk_free_space(): Argument #1 ($directory) must not contain any null bytes
119+
diskfreespace(): Argument #1 ($directory) must not contain any null bytes
120120

121121
--- Done ---

0 commit comments

Comments
 (0)