diff --git a/Cargo.lock b/Cargo.lock index bc033be45..0ae7fc2c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2850,8 +2850,7 @@ checksum = "87dfd5592a8eed7e74f56ad7b125f8234763b805c30f0c7c95c486920026a6ec" [[package]] name = "quick-xml" version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" +source = "git+https://github.com/ruffle-rs/quick-xml?rev=8496365ec1412eb5ba5de350937b6bce352fa0ba#8496365ec1412eb5ba5de350937b6bce352fa0ba" dependencies = [ "memchr", ] diff --git a/core/Cargo.toml b/core/Cargo.toml index 668306381..dddc816f1 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -24,7 +24,7 @@ bitflags = "1.3.2" smallvec = "1.6.1" num-traits = "0.2" num-derive = "0.3" -quick-xml = "0.22.0" +quick-xml = { git = "https://github.com/ruffle-rs/quick-xml", rev = "8496365ec1412eb5ba5de350937b6bce352fa0ba" } downcast-rs = "1.2.0" url = "2.2.2" weak-table = "0.3.0" diff --git a/core/src/xml/tree.rs b/core/src/xml/tree.rs index f682d2c17..543f185f2 100644 --- a/core/src/xml/tree.rs +++ b/core/src/xml/tree.rs @@ -243,13 +243,13 @@ impl<'gc> XmlNode<'gc> { match event { Event::Start(bs) => { - let child = XmlNode::from_start_event(mc, bs, document)?; + let child = XmlNode::from_start_event(mc, bs, document, process_entity)?; self.document().update_idmap(mc, child); self.add_child_to_tree(mc, &mut open_tags, child)?; open_tags.push(child); } Event::Empty(bs) => { - let child = XmlNode::from_start_event(mc, bs, document)?; + let child = XmlNode::from_start_event(mc, bs, document, process_entity)?; self.document().update_idmap(mc, child); self.add_child_to_tree(mc, &mut open_tags, child)?; } @@ -292,16 +292,19 @@ impl<'gc> XmlNode<'gc> { mc: MutationContext<'gc, '_>, bs: BytesStart<'a>, document: XmlDocument<'gc>, + process_entity: bool, ) -> Result { let tag_name = XmlName::from_bytes(bs.name())?; let mut attributes = BTreeMap::new(); for a in bs.attributes() { let attribute = a?; - attributes.insert( - XmlName::from_bytes(attribute.key)?, - String::from_utf8(attribute.value.to_owned().to_vec())?, - ); + let value = if process_entity { + String::from_utf8(attribute.unescaped_value()?.to_owned().to_vec())? + } else { + String::from_utf8(attribute.value.to_owned().to_vec())? + }; + attributes.insert(XmlName::from_bytes(attribute.key)?, value); } Ok(XmlNode(GcCell::allocate( diff --git a/tests/tests/regression_tests.rs b/tests/tests/regression_tests.rs index e3db270a1..b7e3d8d86 100644 --- a/tests/tests/regression_tests.rs +++ b/tests/tests/regression_tests.rs @@ -237,6 +237,7 @@ swf_tests! { (xml_ignore_comments, "avm1/xml_ignore_comments", 1), (xml_ignore_white, "avm1/xml_ignore_white", 1), (xml_inspect_doctype, "avm1/xml_inspect_doctype", 1), + (xml_unescaping, "avm1/xml_unescaping", 1), #[ignore] (xml_inspect_xmldecl, "avm1/xml_inspect_xmldecl", 1), (xml_inspect_createmethods, "avm1/xml_inspect_createmethods", 1), (xml_inspect_parsexml, "avm1/xml_inspect_parsexml", 1), diff --git a/tests/tests/swfs/avm1/xml_unescaping/Test.as b/tests/tests/swfs/avm1/xml_unescaping/Test.as new file mode 100644 index 000000000..9650346a2 --- /dev/null +++ b/tests/tests/swfs/avm1/xml_unescaping/Test.as @@ -0,0 +1,23 @@ +// Compile with: +// mtasc -main -header 200:150:30 Test.as -swf test.swf +class Test { + static function main(current) { + +var xml; +xml = new XML("A & ' B"); +trace(xml.firstChild.firstChild.nodeValue); + +xml = new XML(""); +trace(""); +trace(xml.firstChild.attributes.label); + +xml = new XML("A & &thing; B"); +trace(""); +trace(xml.firstChild.firstChild.nodeValue); + +xml = new XML(""); +trace(""); +trace(xml.firstChild.attributes.label); + + } +} \ No newline at end of file diff --git a/tests/tests/swfs/avm1/xml_unescaping/output.txt b/tests/tests/swfs/avm1/xml_unescaping/output.txt new file mode 100644 index 000000000..5d94c6a13 --- /dev/null +++ b/tests/tests/swfs/avm1/xml_unescaping/output.txt @@ -0,0 +1,7 @@ +A & ' B + +A & ' B + +A & &thing; B + +A & &thing; B diff --git a/tests/tests/swfs/avm1/xml_unescaping/test.swf b/tests/tests/swfs/avm1/xml_unescaping/test.swf new file mode 100644 index 000000000..b3a064c91 Binary files /dev/null and b/tests/tests/swfs/avm1/xml_unescaping/test.swf differ