Skip to content

Commit 2e39386

Browse files
committed
avm2: Handle explicitly imported/used namespace for XML lookup
Fixes ruffle-rs#14792
1 parent 6c420fa commit 2e39386

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

core/src/avm2/multiname.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ pub enum NamespaceSet<'gc> {
2323
}
2424

2525
impl<'gc> NamespaceSet<'gc> {
26+
pub fn new(set: Vec<Namespace<'gc>>, mc: &Mutation<'gc>) -> Self {
27+
if set.len() == 1 {
28+
NamespaceSet::single(set[0])
29+
} else {
30+
NamespaceSet::multiple(set, mc)
31+
}
32+
}
33+
2634
pub fn multiple(set: Vec<Namespace<'gc>>, mc: &Mutation<'gc>) -> Self {
2735
Self::Multiple(Gc::new(mc, set))
2836
}
@@ -469,6 +477,10 @@ impl<'gc> Multiname<'gc> {
469477
AvmString::new(mc, uri)
470478
}
471479

480+
pub fn set_ns(&mut self, ns: NamespaceSet<'gc>) {
481+
self.ns = ns;
482+
}
483+
472484
pub fn set_single_namespace(&mut self, namespace: Namespace<'gc>) {
473485
self.ns = NamespaceSet::Single(namespace);
474486
}

core/src/avm2/object/xml_object.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::avm2::activation::Activation;
44
use crate::avm2::api_version::ApiVersion;
55
use crate::avm2::e4x::{string_to_multiname, E4XNode, E4XNodeKind};
66
use crate::avm2::error::make_error_1087;
7+
use crate::avm2::multiname::NamespaceSet;
78
use crate::avm2::object::script_object::ScriptObjectData;
89
use crate::avm2::object::{ClassObject, Object, ObjectPtr, TObject, XmlListObject};
910
use crate::avm2::string::AvmString;
@@ -647,10 +648,24 @@ fn handle_input_multiname<'gc>(
647648
&& !name.is_any_name()
648649
&& !name.is_any_namespace()
649650
{
650-
name.local_name()
651+
if let Some(mut new_name) = name
652+
.local_name()
651653
.map(|name| string_to_multiname(activation, name))
652-
.unwrap_or(name)
653-
} else {
654-
name
654+
{
655+
// Copy the namespaces from the previous name,
656+
// but make sure to definitely include the public namespace.
657+
if !new_name.is_any_namespace() {
658+
let mut ns = Vec::new();
659+
ns.extend(name.namespace_set());
660+
if !name.contains_public_namespace() {
661+
ns.push(activation.avm2().public_namespace_base_version);
662+
}
663+
new_name.set_ns(NamespaceSet::new(ns, activation.gc()));
664+
}
665+
666+
return new_name;
667+
}
655668
}
669+
670+
name
656671
}

0 commit comments

Comments
 (0)