Skip to content

Commit a54af45

Browse files
committed
Fix memory leak when encoding check fails
zlib_create_dictionary_string() allocates memory, so we can leak memory if there's an early exit before the assignment to the return value. Solve this by moving all validation upwards. Closes GH-17788.
1 parent 4b5c29e commit a54af45

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ PHP NEWS
4141
- Zlib:
4242
. Fixed bug GH-17745 (zlib extension incorrectly handles object arguments).
4343
(nielsdos)
44+
. Fix memory leak when encoding check fails. (nielsdos)
4445

4546
13 Feb 2025, PHP 8.3.17
4647

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Memory leak when passing a dictionary with invalid encoding
3+
--EXTENSIONS--
4+
zlib
5+
--FILE--
6+
<?php
7+
try {
8+
inflate_init(123456, ["dictionary" => "dict"]);
9+
} catch (ValueError $e) {
10+
echo $e->getMessage(), "\n";
11+
}
12+
try {
13+
deflate_init(123456, ["dictionary" => "dict"]);
14+
} catch (ValueError $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
?>
18+
--EXPECT--
19+
Encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE
20+
deflate_init(): Argument #1 ($encoding) must be one of ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP, or ZLIB_ENCODING_DEFLATE

ext/zlib/zlib.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -879,10 +879,6 @@ PHP_FUNCTION(inflate_init)
879879
RETURN_THROWS();
880880
}
881881

882-
if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
883-
RETURN_THROWS();
884-
}
885-
886882
switch (encoding) {
887883
case PHP_ZLIB_ENCODING_RAW:
888884
case PHP_ZLIB_ENCODING_GZIP:
@@ -893,6 +889,10 @@ PHP_FUNCTION(inflate_init)
893889
RETURN_THROWS();
894890
}
895891

892+
if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
893+
RETURN_THROWS();
894+
}
895+
896896
object_init_ex(return_value, inflate_context_ce);
897897
ctx = Z_INFLATE_CONTEXT_P(return_value);
898898

@@ -1132,10 +1132,6 @@ PHP_FUNCTION(deflate_init)
11321132
RETURN_THROWS();
11331133
}
11341134

1135-
if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
1136-
RETURN_THROWS();
1137-
}
1138-
11391135
switch (encoding) {
11401136
case PHP_ZLIB_ENCODING_RAW:
11411137
case PHP_ZLIB_ENCODING_GZIP:
@@ -1146,6 +1142,10 @@ PHP_FUNCTION(deflate_init)
11461142
RETURN_THROWS();
11471143
}
11481144

1145+
if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
1146+
RETURN_THROWS();
1147+
}
1148+
11491149
object_init_ex(return_value, deflate_context_ce);
11501150
ctx = Z_DEFLATE_CONTEXT_P(return_value);
11511151

0 commit comments

Comments
 (0)