Skip to content

Commit 984484a

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Fix memory leaks in ext-tidy
2 parents d49e419 + d8cec14 commit 984484a

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

Diff for: ext/tidy/tests/parsing_file_too_large.phpt

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
--TEST--
2+
Trying to parse a file that is too large (over 4GB)
3+
--EXTENSIONS--
4+
tidy
5+
--SKIPIF--
6+
<?php
7+
if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only");
8+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
9+
?>
10+
--INI--
11+
memory_limit="5G"
12+
--FILE--
13+
<?php
14+
15+
$path = __DIR__ . '/too_large_test.html';
16+
$file = fopen($path, 'w+');
17+
18+
// Write over 4GB
19+
const MIN_FILE_SIZE = 4_294_967_295;
20+
21+
var_dump(fseek($file, MIN_FILE_SIZE+10));
22+
$s = str_repeat("a", 10);
23+
$bytes_written = fwrite($file, $s);
24+
if ($bytes_written === false) {
25+
echo "Didn't write bytes\n";
26+
}
27+
28+
$tidy = new tidy;
29+
try {
30+
var_dump($tidy->parseFile($path));
31+
} catch (\Throwable $e) {
32+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
33+
}
34+
35+
try {
36+
var_dump(tidy_parse_file($path));
37+
} catch (\Throwable $e) {
38+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
39+
}
40+
41+
try {
42+
$tidy = new tidy($path);
43+
} catch (\Throwable $e) {
44+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
45+
}
46+
?>
47+
--CLEAN--
48+
<?php
49+
$path = __DIR__ . '/too_large_test.html';
50+
unlink($path);
51+
?>
52+
--EXPECT--
53+
int(0)
54+
ValueError: Input string is too long
55+
ValueError: Input string is too long
56+
ValueError: Input string is too long

Diff for: ext/tidy/tests/parsing_inexistent_file.phpt

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Trying to parse a non existent file
3+
--EXTENSIONS--
4+
tidy
5+
--FILE--
6+
<?php
7+
8+
$tidy = new tidy;
9+
var_dump($tidy->parseFile("does_not_exist.html"));
10+
11+
var_dump(tidy_parse_file("does_not_exist.html"));
12+
13+
$tidy = new tidy("does_not_exist.html");
14+
?>
15+
--EXPECTF--
16+
Warning: tidy::parseFile(): Cannot load "does_not_exist.html" into memory in %s on line %d
17+
bool(false)
18+
19+
Warning: tidy_parse_file(): Cannot load "does_not_exist.html" into memory in %s on line %d
20+
bool(false)
21+
22+
Warning: tidy::__construct(): Cannot load "does_not_exist.html" into memory in %s on line %d

Diff for: ext/tidy/tidy.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -1069,19 +1069,20 @@ PHP_FUNCTION(tidy_parse_file)
10691069
Z_PARAM_BOOL(use_include_path)
10701070
ZEND_PARSE_PARAMETERS_END();
10711071

1072-
tidy_instantiate(tidy_ce_doc, return_value);
1073-
obj = Z_TIDY_P(return_value);
1074-
10751072
if (!(contents = php_tidy_file_to_mem(ZSTR_VAL(inputfile), use_include_path))) {
10761073
php_error_docref(NULL, E_WARNING, "Cannot load \"%s\" into memory%s", ZSTR_VAL(inputfile), (use_include_path) ? " (using include path)" : "");
10771074
RETURN_FALSE;
10781075
}
10791076

10801077
if (ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(contents))) {
1078+
zend_string_release_ex(contents, 0);
10811079
zend_value_error("Input string is too long");
10821080
RETURN_THROWS();
10831081
}
10841082

1083+
tidy_instantiate(tidy_ce_doc, return_value);
1084+
obj = Z_TIDY_P(return_value);
1085+
10851086
TIDY_APPLY_CONFIG(obj->ptdoc->doc, options_str, options_ht);
10861087

10871088
if (php_tidy_parse_string(obj, ZSTR_VAL(contents), (uint32_t)ZSTR_LEN(contents), enc) == FAILURE) {
@@ -1372,6 +1373,7 @@ PHP_METHOD(tidy, __construct)
13721373
}
13731374

13741375
if (ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(contents))) {
1376+
zend_string_release_ex(contents, 0);
13751377
zend_value_error("Input string is too long");
13761378
RETURN_THROWS();
13771379
}
@@ -1410,6 +1412,7 @@ PHP_METHOD(tidy, parseFile)
14101412
}
14111413

14121414
if (ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(contents))) {
1415+
zend_string_release_ex(contents, 0);
14131416
zend_value_error("Input string is too long");
14141417
RETURN_THROWS();
14151418
}

0 commit comments

Comments
 (0)