Skip to content

Commit 32f9017

Browse files
committed
Implement Dom\HTMLDocument::createFromStream()
1 parent b650bd9 commit 32f9017

File tree

5 files changed

+115
-2
lines changed

5 files changed

+115
-2
lines changed

ext/dom/html_document.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,10 +1004,12 @@ static void dom_html_document_create_from_stream(
10041004
const char *filename
10051005
)
10061006
{
1007+
ZEND_ASSERT(stream != NULL);
1008+
10071009
php_dom_private_data *private_data = NULL;
10081010

10091011
dom_lexbor_libxml2_bridge_application_data application_data;
1010-
application_data.input_name = filename;
1012+
application_data.input_name = filename ? filename : "Entity";
10111013
application_data.current_total_offset = 0;
10121014
application_data.html_no_implied = options & HTML_PARSE_NOIMPLIED;
10131015
dom_reset_line_column_cache(&application_data.cache_tokenizer);
@@ -1232,6 +1234,34 @@ PHP_METHOD(Dom_HTMLDocument, createFromFile)
12321234
php_stream_close(stream);
12331235
}
12341236

1237+
PHP_METHOD(Dom_HTMLDocument, createFromStream)
1238+
{
1239+
php_stream *stream;
1240+
zval *stream_zv;
1241+
const char *document_uri = NULL;
1242+
const char *override_encoding = NULL;
1243+
size_t override_encoding_len, document_uri_len;
1244+
zend_long options = 0;
1245+
if (zend_parse_parameters(
1246+
ZEND_NUM_ARGS(),
1247+
"r|p!lp!",
1248+
&stream_zv,
1249+
&document_uri,
1250+
&document_uri_len,
1251+
&options,
1252+
&override_encoding,
1253+
&override_encoding_len
1254+
) == FAILURE) {
1255+
RETURN_THROWS();
1256+
}
1257+
1258+
php_stream_from_res(stream, Z_RES_P(stream_zv));
1259+
1260+
dom_html_document_create_from_stream(
1261+
return_value, stream, options, override_encoding, override_encoding_len, NULL, document_uri
1262+
);
1263+
}
1264+
12351265
static zend_result dom_write_output_smart_str(void *ctx, const char *buf, size_t size)
12361266
{
12371267
smart_str_appendl((smart_str *) ctx, buf, size);

ext/dom/php_dom.stub.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,9 @@ public static function createEmpty(string $encoding = "UTF-8"): HTMLDocument {}
20422042

20432043
public static function createFromFile(string $path, int $options = 0, ?string $overrideEncoding = null): HTMLDocument {}
20442044

2045+
/** @param resource $stream */
2046+
public static function createFromStream($stream, ?string $documentURI = null, int $options = 0, ?string $overrideEncoding = null): HTMLDocument {}
2047+
20452048
public static function createFromString(string $source, int $options = 0, ?string $overrideEncoding = null): HTMLDocument {}
20462049

20472050
/** @implementation-alias Dom\XMLDocument::saveXml */

ext/dom/php_dom_arginfo.h

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Dom\HTMLDocument::createFromStream() - from memory
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$tmp = fopen("php://memory", "w+");
9+
fwrite($tmp, "<!DOCTYPE html><html><p>Hello world</p></html>");
10+
rewind($tmp);
11+
$dom1 = Dom\HTMLDocument::createFromStream($tmp);
12+
rewind($tmp);
13+
$dom2 = Dom\HTMLDocument::createFromStream($tmp, "http://example.com");
14+
fclose($tmp);
15+
16+
var_dump($dom1->documentURI);
17+
var_dump($dom2->documentURI);
18+
19+
echo $dom1->saveHtml(), "\n";
20+
echo $dom2->saveHtml(), "\n";
21+
22+
?>
23+
--EXPECT--
24+
string(11) "about:blank"
25+
string(18) "http://example.com"
26+
<!DOCTYPE html><html><head></head><body><p>Hello world</p></body></html>
27+
<!DOCTYPE html><html><head></head><body><p>Hello world</p></body></html>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Dom\HTMLDocument::createFromStream() - broken stream
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
class MyStream {
9+
public $context;
10+
private bool $first = true;
11+
12+
public function stream_read(int $count): string|false {
13+
if ($this->first) {
14+
$this->first = false;
15+
return "<!DOCTYPE html><html><p>Hello";
16+
}
17+
throw new Error("broken");
18+
}
19+
20+
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path) {
21+
return true;
22+
}
23+
24+
public function stream_close(): void {
25+
}
26+
27+
public function stream_eof(): bool {
28+
return !$this->first;
29+
}
30+
}
31+
32+
stream_wrapper_register("foo", MyStream::class);
33+
34+
$tmp = fopen("foo://", "r+");
35+
try {
36+
$dom = Dom\HTMLDocument::createFromStream($tmp);
37+
} catch (Error $e) {
38+
echo $e->getMessage(), "\n";
39+
}
40+
fclose($tmp);
41+
42+
?>
43+
--EXPECT--
44+
broken

0 commit comments

Comments
 (0)