Fix newly constructed XML trees not actually containing the XML they just parsed.

This commit is contained in:
David Wendt 2019-12-21 23:57:51 -05:00
parent 960e4dad90
commit e47a1d1e38
2 changed files with 22 additions and 12 deletions

View File

@ -8,7 +8,6 @@ use crate::avm1::xml_object::XMLObject;
use crate::avm1::{Avm1, Error, Object, TObject, UpdateContext, Value};
use crate::xml::{XMLDocument, XMLNode};
use gc_arena::MutationContext;
use std::mem::swap;
/// XMLNode constructor
pub fn xmlnode_constructor<'gc>(
@ -25,12 +24,12 @@ pub fn xmlnode_constructor<'gc>(
this.as_xml_node(),
) {
(Some(Ok(1)), Some(Ok(ref strval)), Some(ref mut this_node)) => {
let mut xmlelement = XMLNode::new_text(ac.gc_context, strval, blank_document);
swap(&mut xmlelement, this_node);
let xmlelement = XMLNode::new_text(ac.gc_context, strval, blank_document);
this_node.swap(ac.gc_context, xmlelement);
}
(Some(Ok(3)), Some(Ok(ref strval)), Some(ref mut this_node)) => {
let mut xmlelement = XMLNode::new_element(ac.gc_context, strval, blank_document)?;
swap(&mut xmlelement, this_node);
let xmlelement = XMLNode::new_element(ac.gc_context, strval, blank_document)?;
this_node.swap(ac.gc_context, xmlelement);
}
//Invalid nodetype ID, string value missing, or not an XMLElement
_ => {}
@ -155,13 +154,11 @@ pub fn xml_constructor<'gc>(
) {
(Some(Ok(ref string)), Some(ref mut this_node)) => {
let xmldoc = XMLDocument::from_str(ac.gc_context, string)?;
swap(&mut xmldoc.as_node(), this_node);
this_node.swap(ac.gc_context, xmldoc.as_node());
}
(None, Some(ref mut this_node)) => {
let xmldoc = XMLDocument::new(ac.gc_context);
swap(&mut xmldoc.as_node(), this_node);
this_node.swap(ac.gc_context, xmldoc.as_node());
}
//Non-string argument or not an XML document
_ => {}
@ -176,7 +173,5 @@ pub fn create_xml_proto<'gc>(
proto: Object<'gc>,
_fn_proto: Object<'gc>,
) -> Object<'gc> {
let xml_proto = XMLObject::empty_node(gc_context, Some(proto));
xml_proto.into()
XMLObject::empty_node(gc_context, Some(proto))
}

View File

@ -9,6 +9,7 @@ use quick_xml::events::{BytesStart, BytesText};
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::fmt;
use std::mem::swap;
/// Represents a node in the XML tree.
#[derive(Copy, Clone, Collect)]
@ -414,6 +415,20 @@ impl<'gc> XMLNode<'gc> {
object.unwrap()
}
/// Swap the contents of this node with another one.
///
/// After this function completes, the current `XMLNode` will contain all
/// data present in the `other` node, and vice versa. References to the node
/// within the tree will *not* be updated.
pub fn swap(&mut self, gc_context: MutationContext<'gc, '_>, other: Self) {
if !GcCell::ptr_eq(self.0, other.0) {
swap(
&mut *self.0.write(gc_context),
&mut *other.0.write(gc_context),
);
}
}
}
impl<'gc> fmt::Debug for XMLNode<'gc> {