Skip to content

Commit 877cb7d

Browse files
cmb69remicollet
authored andcommitted
Fix #74267: segfault with streams and invalid data
If the current character is a line break character, it cannot be a tab or space character, so we would always fail with an invalid sequence error. Obviously, these `scan_stat == 4` conditions are meant to be exclusive. Furthermore, if `in_pp == NULL || in_left_p == NULL` is true, we hit a segfault if we are not returning right away. Obviously, the additional constraints don't make sense, so we remove them. (cherry picked from commit 12c59f6) (cherry picked from commit d149a44) (cherry picked from commit c173da7) (cherry picked from commit 0535796)
1 parent 7958fcc commit 877cb7d

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

ext/standard/filters.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
800800
lb_ptr = inst->lb_ptr;
801801
lb_cnt = inst->lb_cnt;
802802

803-
if ((in_pp == NULL || in_left_p == NULL) && (lb_ptr >=lb_cnt)) {
803+
if (in_pp == NULL || in_left_p == NULL) {
804804
return PHP_CONV_ERR_SUCCESS;
805805
}
806806

@@ -1027,7 +1027,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins
10271027
lb_ptr = inst->lb_ptr;
10281028
lb_cnt = inst->lb_cnt;
10291029

1030-
if ((in_pp == NULL || in_left_p == NULL) && lb_cnt == lb_ptr) {
1030+
if (in_pp == NULL || in_left_p == NULL) {
10311031
if (inst->scan_stat != 0) {
10321032
return PHP_CONV_ERR_UNEXPECTED_EOS;
10331033
}
@@ -1124,8 +1124,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins
11241124
*ps == (unsigned char)inst->lbchars[lb_cnt]) {
11251125
lb_cnt++;
11261126
scan_stat = 5;
1127-
}
1128-
if (*ps != '\t' && *ps != ' ') {
1127+
} else if (*ps != '\t' && *ps != ' ') {
11291128
err = PHP_CONV_ERR_INVALID_SEQ;
11301129
goto out;
11311130
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #74267 (segfault with streams and invalid data)
3+
--FILE--
4+
<?php
5+
$stream = fopen('php://memory', 'w');
6+
stream_filter_append($stream, 'convert.quoted-printable-decode', STREAM_FILTER_WRITE, ['line-break-chars' => "\r\n"]);
7+
8+
$lines = [
9+
"\r\n",
10+
" -=()\r\n",
11+
" -=\r\n",
12+
"\r\n"
13+
];
14+
15+
foreach ($lines as $line) {
16+
fwrite($stream, $line);
17+
}
18+
19+
fclose($stream);
20+
echo "done\n";
21+
?>
22+
--EXPECTF--
23+
Warning: fwrite(): stream filter (convert.quoted-printable-decode): invalid byte sequence in %s on line %d
24+
25+
Warning: fwrite(): stream filter (convert.quoted-printable-decode): invalid byte sequence in %s on line %d
26+
done

0 commit comments

Comments
 (0)