From fb3c4cd3074550a272c914c45d578730b07f21f6 Mon Sep 17 00:00:00 2001 From: sleepycatcoding <131554884+sleepycatcoding@users.noreply.github.com> Date: Mon, 30 Oct 2023 00:06:54 +0200 Subject: [PATCH] avm2: Fix E4X [[Replace]] implementation bug We were incorrectly returning for XML attributes. Fixes #13780. --- core/src/avm2/e4x.rs | 10 +++++----- tests/tests/swfs/avm2/issue_13780/Test.as | 18 ++++++++++++++++++ tests/tests/swfs/avm2/issue_13780/output.txt | 12 ++++++++++++ tests/tests/swfs/avm2/issue_13780/test.swf | Bin 0 -> 905 bytes tests/tests/swfs/avm2/issue_13780/test.toml | 1 + 5 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 tests/tests/swfs/avm2/issue_13780/Test.as create mode 100644 tests/tests/swfs/avm2/issue_13780/output.txt create mode 100644 tests/tests/swfs/avm2/issue_13780/test.swf create mode 100644 tests/tests/swfs/avm2/issue_13780/test.toml diff --git a/core/src/avm2/e4x.rs b/core/src/avm2/e4x.rs index 8e535997f..a7b727a2b 100644 --- a/core/src/avm2/e4x.rs +++ b/core/src/avm2/e4x.rs @@ -488,11 +488,11 @@ impl<'gc> E4XNode<'gc> { } // 5. If Type(V) is XML and V.[[Class]] ∈ {"element", "comment", "processing-instruction", "text"} - if let Some(xml) = value.as_object().and_then(|x| x.as_xml_object()) { - if matches!(*xml.node().kind(), E4XNodeKind::Attribute(_)) { - return Ok(()); - } - + if let Some(xml) = value + .as_object() + .and_then(|x| x.as_xml_object()) + .filter(|x| !matches!(*x.node().kind(), E4XNodeKind::Attribute(_))) + { // 5.a. If V.[[Class]] is “element” and (V is x or an ancestor of x) throw an Error exception if matches!(*xml.node().kind(), E4XNodeKind::Element { .. }) && self.ancestors().any(|x| E4XNode::ptr_eq(x, *xml.node())) diff --git a/tests/tests/swfs/avm2/issue_13780/Test.as b/tests/tests/swfs/avm2/issue_13780/Test.as new file mode 100644 index 000000000..387c2fa2c --- /dev/null +++ b/tests/tests/swfs/avm2/issue_13780/Test.as @@ -0,0 +1,18 @@ +package { + import flash.display.Sprite; + + public class Test extends Sprite {} +} + +// Issue 13780: Replace does not work with attribute nodes. + +var xml = new XML(''); +var attr = xml.@attr[0]; // Fooled by XMLList again... +trace(attr); +trace(attr.nodeKind()); + +var target = new XML(''); + +trace(target); +target.replace(1, attr); +trace(target); \ No newline at end of file diff --git a/tests/tests/swfs/avm2/issue_13780/output.txt b/tests/tests/swfs/avm2/issue_13780/output.txt new file mode 100644 index 000000000..78fa77a07 --- /dev/null +++ b/tests/tests/swfs/avm2/issue_13780/output.txt @@ -0,0 +1,12 @@ +val +attribute + + + + + + + + val + + diff --git a/tests/tests/swfs/avm2/issue_13780/test.swf b/tests/tests/swfs/avm2/issue_13780/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..a29ae014bb65fcf0cdc544f8539dd0f8ebb556d3 GIT binary patch literal 905 zcmV;419tpFS5p)*1poke0fkdrZ{tK1o*6r~leW3AOSWZM6iTI1K{8H)R!TRGT5Tx1 z+=@0JR!C7avB!z2V_Wv*vJVJ}SCIG(yzn=8Ks@jk9{2-1?PK@_<;*1A?mjWn8K2Ad zojEh-c!BhP5X%3G&@M*Z(jG$S`&-X3LhZ!$j-PbTD~m}GrpI8N9FB#Ek13tc=e2pW z79}HEZ?#&~ZqP=f3W#d@EEH@}4byiHJ1Rk!r%vL>!jHm=Ovr}ORGb_hZnC=0i=^>1 z2~%m=Oql4fI1YS=$#is4O~;XQIcGCo^#YcT+w=w~Il>nK z@0`WV8S~0{z!#OX8@d9o5fba()Y;kG(gQ|~DYmLhFvTOS*YJPfAp=A& zUjEsHF+u3(qo2O}5wt&YU-DF--){d-5RwsP7Ew)t-qMw|Psh=O(;4?KBPsyyhogaN z-h&4cP-AIUeyQAcRG{YiX&kU;MlVi$!HtXIx7-nh4`(nST?jD&?M=4VST4Qkj`Ra% z4J|zm1y7hG{25<+%CE#9MliE}$P?}9XP=hZGZs{s5Xs3tX#2FIOG8}^iaThu-rkG{ zbE6@zInjik^_sL{+xO{k>IZP6jDXX)6-F-q#1Gwf+es9OPTLv#fm^2=rE#q^L7@s^ zCLF4E_?^LE6b(c)aJlD)z8vIM=7~q*WiaFt-4lk)(ydu5f@sc`GJ+eWm3-U z;&L`qv`R!HhFLNRHZ{W}rkSx!EoW+5rnYU8oqPe`#U^_Zu>0PGtSmPmUiJWaIWV%b3x|Mkd%`Gv=UhmeDaPC@w(Z@F=4qw2j= literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/avm2/issue_13780/test.toml b/tests/tests/swfs/avm2/issue_13780/test.toml new file mode 100644 index 000000000..cf6123969 --- /dev/null +++ b/tests/tests/swfs/avm2/issue_13780/test.toml @@ -0,0 +1 @@ +num_ticks = 1