Skip to content

Commit 0535796

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)
1 parent 9f08040 commit 0535796

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
@@ -790,7 +790,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins
790790
lb_ptr = inst->lb_ptr;
791791
lb_cnt = inst->lb_cnt;
792792

793-
if ((in_pp == NULL || in_left_p == NULL) && (lb_ptr >=lb_cnt)) {
793+
if (in_pp == NULL || in_left_p == NULL) {
794794
return PHP_CONV_ERR_SUCCESS;
795795
}
796796

@@ -1018,7 +1018,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins
10181018
lb_ptr = inst->lb_ptr;
10191019
lb_cnt = inst->lb_cnt;
10201020

1021-
if ((in_pp == NULL || in_left_p == NULL) && lb_cnt == lb_ptr) {
1021+
if (in_pp == NULL || in_left_p == NULL) {
10221022
if (inst->scan_stat != 0) {
10231023
return PHP_CONV_ERR_UNEXPECTED_EOS;
10241024
}
@@ -1115,8 +1115,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins
11151115
*ps == (unsigned char)inst->lbchars[lb_cnt]) {
11161116
lb_cnt++;
11171117
scan_stat = 5;
1118-
}
1119-
if (*ps != '\t' && *ps != ' ') {
1118+
} else if (*ps != '\t' && *ps != ' ') {
11201119
err = PHP_CONV_ERR_INVALID_SEQ;
11211120
goto out;
11221121
}
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)