diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-06-08 23:19:43 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-06-08 23:19:43 +0200 |
commit | 12c59f6660706321f9d42c55421ff6864439c8b7 (patch) | |
tree | 0299fd1b063fac265d0b5a84eb1331ec831d8862 | |
parent | ceae81665cc6d8dadf2103a3f9266150b076ab2a (diff) | |
download | php-git-12c59f6660706321f9d42c55421ff6864439c8b7.tar.gz |
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.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/standard/filters.c | 7 | ||||
-rw-r--r-- | ext/standard/tests/filters/bug74267.phpt | 26 |
3 files changed, 32 insertions, 4 deletions
@@ -14,6 +14,9 @@ PHP NEWS . Fixed bug #79664 (PDOStatement::getColumnMeta fails on empty result set). (cmb) +- Standard: + . Fixed bug #74267 (segfault with streams and invalid data). (cmb) + ?? ??? ????, PHP 7.3.19 - Core: diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 7b039cd18f..9b2dcf08aa 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -788,7 +788,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins lb_ptr = inst->lb_ptr; lb_cnt = inst->lb_cnt; - if ((in_pp == NULL || in_left_p == NULL) && (lb_ptr >=lb_cnt)) { + if (in_pp == NULL || in_left_p == NULL) { return PHP_CONV_ERR_SUCCESS; } @@ -1016,7 +1016,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins lb_ptr = inst->lb_ptr; lb_cnt = inst->lb_cnt; - if ((in_pp == NULL || in_left_p == NULL) && lb_cnt == lb_ptr) { + if (in_pp == NULL || in_left_p == NULL) { if (inst->scan_stat != 0) { return PHP_CONV_ERR_UNEXPECTED_EOS; } @@ -1113,8 +1113,7 @@ static php_conv_err_t php_conv_qprint_decode_convert(php_conv_qprint_decode *ins *ps == (unsigned char)inst->lbchars[lb_cnt]) { lb_cnt++; scan_stat = 5; - } - if (*ps != '\t' && *ps != ' ') { + } else if (*ps != '\t' && *ps != ' ') { err = PHP_CONV_ERR_INVALID_SEQ; goto out; } diff --git a/ext/standard/tests/filters/bug74267.phpt b/ext/standard/tests/filters/bug74267.phpt new file mode 100644 index 0000000000..17d7996b7f --- /dev/null +++ b/ext/standard/tests/filters/bug74267.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #74267 (segfault with streams and invalid data) +--FILE-- +<?php +$stream = fopen('php://memory', 'w'); +stream_filter_append($stream, 'convert.quoted-printable-decode', STREAM_FILTER_WRITE, ['line-break-chars' => "\r\n"]); + +$lines = [ + "\r\n", + " -=()\r\n", + " -=\r\n", + "\r\n" + ]; + +foreach ($lines as $line) { + fwrite($stream, $line); +} + +fclose($stream); +echo "done\n"; +?> +--EXPECTF-- +Warning: fwrite(): stream filter (convert.quoted-printable-decode): invalid byte sequence in %s on line %d + +Warning: fwrite(): stream filter (convert.quoted-printable-decode): invalid byte sequence in %s on line %d +done |