avm2: Only reject a single explicit namespace in XML

This commit is contained in:
Tom Schuster 2023-03-26 13:26:32 +02:00 committed by Aaron Hill
parent 35528913bf
commit 5a18a409f7
7 changed files with 47 additions and 5 deletions

View File

@ -324,6 +324,13 @@ impl<'gc> Multiname<'gc> {
} }
} }
pub fn has_explicit_namespace(&self) -> bool {
match self.ns {
NamespaceSet::Single(ns) => ns.is_namespace() && !ns.is_public(),
NamespaceSet::Multiple(_) => false,
}
}
/// Indicates if this multiname matches any type. /// Indicates if this multiname matches any type.
pub fn is_any_name(&self) -> bool { pub fn is_any_name(&self) -> bool {
self.name.is_none() self.name.is_none()

View File

@ -184,7 +184,7 @@ impl<'gc> TObject<'gc> for XmlListObject<'gc> {
// FIXME - implement everything from E4X spec (XMLListObject::getMultinameProperty in avmplus) // FIXME - implement everything from E4X spec (XMLListObject::getMultinameProperty in avmplus)
let mut write = self.0.write(activation.context.gc_context); let mut write = self.0.write(activation.context.gc_context);
if name.contains_public_namespace() { if !name.has_explicit_namespace() {
if let Some(local_name) = name.local_name() { if let Some(local_name) = name.local_name() {
if let Ok(index) = local_name.parse::<usize>() { if let Ok(index) = local_name.parse::<usize>() {
if let Some(child) = write.children.get_mut(index) { if let Some(child) = write.children.get_mut(index) {

View File

@ -108,7 +108,7 @@ impl<'gc> TObject<'gc> for XmlObject<'gc> {
// FIXME - implement everything from E4X spec (XMLObject::getMultinameProperty in avmplus) // FIXME - implement everything from E4X spec (XMLObject::getMultinameProperty in avmplus)
let read = self.0.read(); let read = self.0.read();
if name.contains_public_namespace() { if !name.has_explicit_namespace() {
if let Some(local_name) = name.local_name() { if let Some(local_name) = name.local_name() {
// The only supported numerical index is 0 // The only supported numerical index is 0
if let Ok(index) = local_name.parse::<usize>() { if let Ok(index) = local_name.parse::<usize>() {
@ -195,7 +195,7 @@ impl<'gc> TObject<'gc> for XmlObject<'gc> {
// FIXME - see if we can deduplicate this with get_property_local in // FIXME - see if we can deduplicate this with get_property_local in
// an efficient way // an efficient way
if name.contains_public_namespace() { if !name.has_explicit_namespace() {
if let Some(local_name) = name.local_name() { if let Some(local_name) = name.local_name() {
// The only supported numerical index is 0 // The only supported numerical index is 0
if let Ok(index) = local_name.parse::<usize>() { if let Ok(index) = local_name.parse::<usize>() {
@ -226,8 +226,12 @@ impl<'gc> TObject<'gc> for XmlObject<'gc> {
value: Value<'gc>, value: Value<'gc>,
activation: &mut Activation<'_, 'gc>, activation: &mut Activation<'_, 'gc>,
) -> Result<(), Error<'gc>> { ) -> Result<(), Error<'gc>> {
if !name.contains_public_namespace() { if name.has_explicit_namespace() {
return Err("Can not set non-public name yet".into()); return Err(format!(
"Can not set property {:?} with an explicit namespace yet",
name
)
.into());
} }
let mc = activation.context.gc_context; let mc = activation.context.gc_context;

View File

@ -0,0 +1,27 @@
package {
import flash.display.Sprite;
public class Test extends Sprite { }
}
var xml = <xml xmlns:example="http://example.org/">
<foo>abc</foo>
<example:hello>world</example:hello>
</xml>;
trace("xml.*::foo.toString()", xml.*::foo.toString());
trace("xml.*::hello.toString()", xml.*::hello.toString());
var ns = new Namespace("http://example.org/");
// Enable these tests when namespaces are supported.
// trace("xml.ns::foo.toString()", xml.ns::foo.toString());
// trace("xml.hello.toString()", xml.hello.toString());
// xml.ns::test = "abc";
try {
trace("xml.ns::test", xml.ns::test);
} catch (e) {
// This should not actually error.
trace(e.toString());
}

View File

@ -0,0 +1,3 @@
xml.*::foo.toString() abc
xml.*::hello.toString() world
ReferenceError: Error #1069: Property http://example.org/::test not found on XML and there is no default value.

Binary file not shown.

View File

@ -0,0 +1 @@
num_frames = 1