1
0
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:
Ilija Tovilo
2025-09-12 14:03:01 +02:00
parent 707f78528c
commit 1aafd3e4eb
3 changed files with 33 additions and 8 deletions

3
NEWS
View File

@@ -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)

View File

@@ -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;
}

View 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)