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