Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ PHP NEWS
sockets. (David Carlier)

- Standard:
. Fixed quoted_printable_decode() truncating input at NUL bytes. (Weilin Du)
. Fixed version_compare() silently truncating version strings at NUL bytes by
rejecting such input. (Weilin Du)
. Fixed bug #60110 (fclose(), file_put_contents(), copy() do not return false
properly). (Jakub Zelenka, Ilija Tovilo)
. Fixed three Windows-only proc_open() defects: an uninitialized
Expand Down
16 changes: 9 additions & 7 deletions ext/standard/quot_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,22 +194,24 @@ PHP_FUNCTION(quoted_printable_decode)
char *str_in;
zend_string *str_out;
size_t i = 0, j = 0, k;
size_t len;

ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(arg1)
ZEND_PARSE_PARAMETERS_END();

if (ZSTR_LEN(arg1) == 0) {
len = ZSTR_LEN(arg1);
if (len == 0) {
/* shortcut */
RETURN_EMPTY_STRING();
}

str_in = ZSTR_VAL(arg1);
str_out = zend_string_alloc(ZSTR_LEN(arg1), 0);
while (str_in[i]) {
str_out = zend_string_alloc(len, 0);
while (i < len) {
switch (str_in[i]) {
case '=':
if (str_in[i + 1] && str_in[i + 2] &&
if (len - i > 2 &&
isxdigit((unsigned char)str_in[i + 1]) &&
isxdigit((unsigned char)str_in[i + 2]))
{
Expand All @@ -218,15 +220,15 @@ PHP_FUNCTION(quoted_printable_decode)
i += 3;
} else /* check for soft line break according to RFC 2045*/ {
k = 1;
while (str_in[i + k] && ((str_in[i + k] == 32) || (str_in[i + k] == 9))) {
while (k < len - i && ((str_in[i + k] == 32) || (str_in[i + k] == 9))) {
/* Possibly, skip spaces/tabs at the end of line */
k++;
}
if (!str_in[i + k]) {
if (k == len - i) {
/* End of line reached */
i += k;
}
else if ((str_in[i + k] == 13) && (str_in[i + k + 1] == 10)) {
else if ((str_in[i + k] == 13) && k + 1 < len - i && (str_in[i + k + 1] == 10)) {
/* CRLF */
i += k + 2;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--TEST--
quoted_printable_decode() processes input after NUL bytes
--FILE--
<?php
$input = "abc\0d=41f";
$stream = fopen('php://temp', 'w+');
fwrite($stream, $input);
rewind($stream);
stream_filter_append($stream, 'convert.quoted-printable-decode', STREAM_FILTER_READ);
var_dump(quoted_printable_decode($input) === stream_get_contents($stream));
fclose($stream);

foreach ([
"abc\0def",
'A=00B',
"A\0=42",
"A=\0B",
"A= \0B",
"A=\r\n\0B",
"A=0\0B",
'A=',
'A= ',
] as $input) {
echo bin2hex(quoted_printable_decode($input)), "\n";
}
?>
--EXPECT--
bool(true)
61626300646566
410042
410042
413d0042
413d200042
410042
413d300042
41
41
26 changes: 26 additions & 0 deletions ext/standard/tests/versioning/version_compare_null_bytes.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
version_compare() rejects NUL bytes in version strings
--FILE--
<?php
foreach ([
["1.0\0suffix", '1.0'],
['1.0', "1.0\0suffix"],
["\0", '1.0'],
['1.0', "\0"],
] as [$version1, $version2]) {
try {
version_compare($version1, $version2, 'eq');
} catch (ValueError $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
}
var_dump(version_compare('1.0', '1.0'));
var_dump(version_compare('1.0', '1.0', 'eq'));
?>
--EXPECT--
ValueError: version_compare(): Argument #1 ($version1) must not contain any null bytes
ValueError: version_compare(): Argument #2 ($version2) must not contain any null bytes
ValueError: version_compare(): Argument #1 ($version1) must not contain any null bytes
ValueError: version_compare(): Argument #2 ($version2) must not contain any null bytes
int(0)
bool(true)
4 changes: 2 additions & 2 deletions ext/standard/versioning.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ PHP_FUNCTION(version_compare)
int compare;

ZEND_PARSE_PARAMETERS_START(2, 3)
Z_PARAM_STRING(v1, v1_len)
Z_PARAM_STRING(v2, v2_len)
Z_PARAM_PATH(v1, v1_len)
Z_PARAM_PATH(v2, v2_len)
Z_PARAM_OPTIONAL
Z_PARAM_STR_OR_NULL(op)
ZEND_PARSE_PARAMETERS_END();
Expand Down
Loading