mirror of
https://github.com/servo/servo.git
synced 2025-08-02 04:00:32 +01:00
Ensure parsers initiated from DOMParser always complete. (#33056)
* Ensure parsers initiated from DOMParser always complete. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Add test for parseFromString with async parser. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Add expected failure. Signed-off-by: Josh Matthews <josh@joshmatthews.net> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
3cc91e655f
commit
69185c4af1
5 changed files with 36 additions and 34 deletions
|
@ -128,12 +128,6 @@ pub struct ServoParser {
|
||||||
prefetch_input: DomRefCell<BufferQueue>,
|
prefetch_input: DomRefCell<BufferQueue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
enum LastChunkState {
|
|
||||||
Received,
|
|
||||||
NotReceived,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ElementAttribute {
|
pub struct ElementAttribute {
|
||||||
name: QualName,
|
name: QualName,
|
||||||
value: DOMString,
|
value: DOMString,
|
||||||
|
@ -161,7 +155,6 @@ impl ServoParser {
|
||||||
ServoParser::new(
|
ServoParser::new(
|
||||||
document,
|
document,
|
||||||
Tokenizer::AsyncHtml(self::async_html::Tokenizer::new(document, url, None)),
|
Tokenizer::AsyncHtml(self::async_html::Tokenizer::new(document, url, None)),
|
||||||
LastChunkState::NotReceived,
|
|
||||||
ParserKind::Normal,
|
ParserKind::Normal,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -173,14 +166,13 @@ impl ServoParser {
|
||||||
None,
|
None,
|
||||||
ParsingAlgorithm::Normal,
|
ParsingAlgorithm::Normal,
|
||||||
)),
|
)),
|
||||||
LastChunkState::NotReceived,
|
|
||||||
ParserKind::Normal,
|
ParserKind::Normal,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set as the document's current parser and initialize with `input`, if given.
|
// Set as the document's current parser and initialize with `input`, if given.
|
||||||
if let Some(input) = input {
|
if let Some(input) = input {
|
||||||
parser.parse_string_chunk(String::from(input));
|
parser.parse_complete_string_chunk(String::from(input));
|
||||||
} else {
|
} else {
|
||||||
parser.document.set_current_parser(Some(&parser));
|
parser.document.set_current_parser(Some(&parser));
|
||||||
}
|
}
|
||||||
|
@ -239,10 +231,9 @@ impl ServoParser {
|
||||||
Some(fragment_context),
|
Some(fragment_context),
|
||||||
ParsingAlgorithm::Fragment,
|
ParsingAlgorithm::Fragment,
|
||||||
)),
|
)),
|
||||||
LastChunkState::Received,
|
|
||||||
ParserKind::Normal,
|
ParserKind::Normal,
|
||||||
);
|
);
|
||||||
parser.parse_string_chunk(String::from(input));
|
parser.parse_complete_string_chunk(String::from(input));
|
||||||
|
|
||||||
// Step 14.
|
// Step 14.
|
||||||
let root_element = document.GetDocumentElement().expect("no document element");
|
let root_element = document.GetDocumentElement().expect("no document element");
|
||||||
|
@ -260,7 +251,6 @@ impl ServoParser {
|
||||||
None,
|
None,
|
||||||
ParsingAlgorithm::Normal,
|
ParsingAlgorithm::Normal,
|
||||||
)),
|
)),
|
||||||
LastChunkState::NotReceived,
|
|
||||||
ParserKind::ScriptCreated,
|
ParserKind::ScriptCreated,
|
||||||
);
|
);
|
||||||
*parser.bom_sniff.borrow_mut() = None;
|
*parser.bom_sniff.borrow_mut() = None;
|
||||||
|
@ -271,13 +261,12 @@ impl ServoParser {
|
||||||
let parser = ServoParser::new(
|
let parser = ServoParser::new(
|
||||||
document,
|
document,
|
||||||
Tokenizer::Xml(self::xml::Tokenizer::new(document, url)),
|
Tokenizer::Xml(self::xml::Tokenizer::new(document, url)),
|
||||||
LastChunkState::NotReceived,
|
|
||||||
ParserKind::Normal,
|
ParserKind::Normal,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set as the document's current parser and initialize with `input`, if given.
|
// Set as the document's current parser and initialize with `input`, if given.
|
||||||
if let Some(input) = input {
|
if let Some(input) = input {
|
||||||
parser.parse_string_chunk(String::from(input));
|
parser.parse_complete_string_chunk(String::from(input));
|
||||||
} else {
|
} else {
|
||||||
parser.document.set_current_parser(Some(&parser));
|
parser.document.set_current_parser(Some(&parser));
|
||||||
}
|
}
|
||||||
|
@ -421,12 +410,7 @@ impl ServoParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(crown::unrooted_must_root)]
|
#[allow(crown::unrooted_must_root)]
|
||||||
fn new_inherited(
|
fn new_inherited(document: &Document, tokenizer: Tokenizer, kind: ParserKind) -> Self {
|
||||||
document: &Document,
|
|
||||||
tokenizer: Tokenizer,
|
|
||||||
last_chunk_state: LastChunkState,
|
|
||||||
kind: ParserKind,
|
|
||||||
) -> Self {
|
|
||||||
ServoParser {
|
ServoParser {
|
||||||
reflector: Reflector::new(),
|
reflector: Reflector::new(),
|
||||||
document: Dom::from_ref(document),
|
document: Dom::from_ref(document),
|
||||||
|
@ -435,7 +419,7 @@ impl ServoParser {
|
||||||
network_input: DomRefCell::new(BufferQueue::default()),
|
network_input: DomRefCell::new(BufferQueue::default()),
|
||||||
script_input: DomRefCell::new(BufferQueue::default()),
|
script_input: DomRefCell::new(BufferQueue::default()),
|
||||||
tokenizer: DomRefCell::new(tokenizer),
|
tokenizer: DomRefCell::new(tokenizer),
|
||||||
last_chunk_received: Cell::new(last_chunk_state == LastChunkState::Received),
|
last_chunk_received: Cell::new(false),
|
||||||
suspended: Default::default(),
|
suspended: Default::default(),
|
||||||
script_nesting_level: Default::default(),
|
script_nesting_level: Default::default(),
|
||||||
aborted: Default::default(),
|
aborted: Default::default(),
|
||||||
|
@ -446,19 +430,9 @@ impl ServoParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(crown::unrooted_must_root)]
|
#[allow(crown::unrooted_must_root)]
|
||||||
fn new(
|
fn new(document: &Document, tokenizer: Tokenizer, kind: ParserKind) -> DomRoot<Self> {
|
||||||
document: &Document,
|
|
||||||
tokenizer: Tokenizer,
|
|
||||||
last_chunk_state: LastChunkState,
|
|
||||||
kind: ParserKind,
|
|
||||||
) -> DomRoot<Self> {
|
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(ServoParser::new_inherited(
|
Box::new(ServoParser::new_inherited(document, tokenizer, kind)),
|
||||||
document,
|
|
||||||
tokenizer,
|
|
||||||
last_chunk_state,
|
|
||||||
kind,
|
|
||||||
)),
|
|
||||||
document.window(),
|
document.window(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -579,9 +553,10 @@ impl ServoParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string_chunk(&self, input: String) {
|
fn parse_complete_string_chunk(&self, input: String) {
|
||||||
self.document.set_current_parser(Some(self));
|
self.document.set_current_parser(Some(self));
|
||||||
self.push_string_input_chunk(input);
|
self.push_string_input_chunk(input);
|
||||||
|
self.last_chunk_received.set(true);
|
||||||
if !self.suspended.get() {
|
if !self.suspended.get() {
|
||||||
self.parse_sync();
|
self.parse_sync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
[responsexml-non-well-formed.htm]
|
[responsexml-non-well-formed.htm]
|
||||||
|
[XMLHttpRequest: responseXML non well-formed tests]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
[XMLHttpRequest: responseXML non well-formed tests 1]
|
[XMLHttpRequest: responseXML non well-formed tests 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
7
tests/wpt/mozilla/meta/MANIFEST.json
vendored
7
tests/wpt/mozilla/meta/MANIFEST.json
vendored
|
@ -12632,6 +12632,13 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"DOMParser-parseFromString.html": [
|
||||||
|
"38715db5d923e4f153e2c4a2679f644fe1e6d14d",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"DOMParser.html": [
|
"DOMParser.html": [
|
||||||
"f386a3e0191af2c70dcb05790ce7db15dd5ccbf1",
|
"f386a3e0191af2c70dcb05790ce7db15dd5ccbf1",
|
||||||
[
|
[
|
||||||
|
|
2
tests/wpt/mozilla/meta/mozilla/DOMParser-parseFromString.html.ini
vendored
Normal file
2
tests/wpt/mozilla/meta/mozilla/DOMParser-parseFromString.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[DOMParser-parseFromString.html]
|
||||||
|
prefs: ["dom.servoparser.async_html_tokenizer.enabled:true"]
|
15
tests/wpt/mozilla/tests/mozilla/DOMParser-parseFromString.html
vendored
Normal file
15
tests/wpt/mozilla/tests/mozilla/DOMParser-parseFromString.html
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!doctype html>
|
||||||
|
<head>
|
||||||
|
<title>Verify that parseFromString does not panic</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<iframe src="missing"></iframe>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
{
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString("", "text/html");
|
||||||
|
assert_equals(doc.URL, document.URL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue