mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix bzopen() stream mode validation
The previous conditions were unreadable and incorrect. Extract the primary mode first, then compare it to the allowed values. Fixes GH-19810 Closes GH-19815
This commit is contained in:
3
NEWS
3
NEWS
@@ -18,6 +18,9 @@ PHP NEWS
|
||||
. Casting floats that are not representable as ints now emits a warning.
|
||||
(Girgias)
|
||||
|
||||
- Bz2:
|
||||
. Fixed bug GH-19810 (Broken bzopen() stream mode validation). (ilutov)
|
||||
|
||||
- Curl:
|
||||
. Fix cloning of CURLOPT_POSTFIELDS when using the clone operator instead
|
||||
of the curl_copy_handle() function to clone a CurlHandle. (timwolla)
|
||||
|
||||
@@ -366,10 +366,23 @@ PHP_FUNCTION(bzopen)
|
||||
php_stream_from_zval(stream, file);
|
||||
stream_mode_len = strlen(stream->mode);
|
||||
|
||||
if (stream_mode_len != 1 && !(stream_mode_len == 2 && memchr(stream->mode, 'b', 2))) {
|
||||
php_error_docref(NULL, E_WARNING, "Cannot use stream opened in mode '%s'", stream->mode);
|
||||
RETURN_FALSE;
|
||||
} else if (stream_mode_len == 1 && stream->mode[0] != 'r' && stream->mode[0] != 'w' && stream->mode[0] != 'a' && stream->mode[0] != 'x') {
|
||||
char primary_stream_mode;
|
||||
if (stream_mode_len == 1) {
|
||||
primary_stream_mode = stream->mode[0];
|
||||
} else if (stream_mode_len == 2) {
|
||||
char secondary_stream_mode = 0;
|
||||
if (stream->mode[0] != 'b') {
|
||||
primary_stream_mode = stream->mode[0];
|
||||
secondary_stream_mode = stream->mode[1];
|
||||
} else {
|
||||
primary_stream_mode = stream->mode[1];
|
||||
secondary_stream_mode = stream->mode[0];
|
||||
}
|
||||
if (secondary_stream_mode != 'b') {
|
||||
goto unsupported_mode;
|
||||
}
|
||||
} else {
|
||||
unsupported_mode:
|
||||
php_error_docref(NULL, E_WARNING, "Cannot use stream opened in mode '%s'", stream->mode);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@@ -377,16 +390,14 @@ PHP_FUNCTION(bzopen)
|
||||
switch(mode[0]) {
|
||||
case 'r':
|
||||
/* only "r" and "rb" are supported */
|
||||
if (stream->mode[0] != mode[0] && !(stream_mode_len == 2 && stream->mode[1] != mode[0])) {
|
||||
if (primary_stream_mode != 'r') {
|
||||
php_error_docref(NULL, E_WARNING, "Cannot read from a stream opened in write only mode");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
/* support only "w"(b), "a"(b), "x"(b) */
|
||||
if (stream->mode[0] != mode[0] && !(stream_mode_len == 2 && stream->mode[1] != mode[0])
|
||||
&& stream->mode[0] != 'a' && !(stream_mode_len == 2 && stream->mode[1] != 'a')
|
||||
&& stream->mode[0] != 'x' && !(stream_mode_len == 2 && stream->mode[1] != 'x')) {
|
||||
if (!strchr("wax", primary_stream_mode)) {
|
||||
php_error_docref(NULL, E_WARNING, "cannot write to a stream opened in read only mode");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
11
ext/bz2/tests/gh19810.phpt
Normal file
11
ext/bz2/tests/gh19810.phpt
Normal file
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
GH-19810: bzopen() stream mode validation
|
||||
--EXTENSIONS--
|
||||
bz2
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(bzopen(STDERR, 'r'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: bzopen(): Cannot read from a stream opened in write only mode in %s on line %d
|
||||
bool(false)
|
||||
Reference in New Issue
Block a user