avm2: Ignore mismatched end tags in E4X

This commit is contained in:
Tom Schuster 2024-07-08 21:16:23 +02:00 committed by TÖRÖK Attila
parent 69abfa4528
commit 5aeae40bc5
2 changed files with 34 additions and 5 deletions

View File

@ -5,7 +5,7 @@ use std::{
use gc_arena::{Collect, GcCell, Mutation}; use gc_arena::{Collect, GcCell, Mutation};
use quick_xml::{ use quick_xml::{
errors::SyntaxError as XmlSyntaxError, errors::{IllFormedError, SyntaxError as XmlSyntaxError},
events::{attributes::AttrError as XmlAttrError, BytesStart, Event}, events::{attributes::AttrError as XmlAttrError, BytesStart, Event},
name::ResolveResult, name::ResolveResult,
Error as XmlError, NsReader, Error as XmlError, NsReader,
@ -14,7 +14,7 @@ use quick_xml::{
use crate::{avm2::TObject, xml::custom_unescape}; use crate::{avm2::TObject, xml::custom_unescape};
use super::{ use super::{
error::{make_error_1010, make_error_1118, type_error}, error::{make_error_1010, make_error_1085, make_error_1118, type_error},
object::{E4XOrXml, FunctionObject, NamespaceObject}, object::{E4XOrXml, FunctionObject, NamespaceObject},
string::AvmString, string::AvmString,
Activation, Error, Multiname, Value, Activation, Error, Multiname, Value,
@ -850,9 +850,24 @@ impl<'gc> E4XNode<'gc> {
} }
loop { loop {
let event = parser let event = match parser.read_event() {
.read_event() Ok(event) => event,
.map_err(|e| make_xml_error(activation, e))?; Err(XmlError::IllFormed(IllFormedError::MismatchedEndTag { expected, found })) => {
// We must accept </a/>, </a />, and </a b="c">
// TODO: Reject </a bc>, </a//>, <a //> etc.
if let Some(rest) = found.strip_prefix(&expected) {
if rest.starts_with([' ', '\t', '/']) {
let node = open_tags.pop().unwrap();
if open_tags.is_empty() {
top_level.push(node);
}
continue;
}
}
return Err(make_error_1085(activation, &expected));
}
Err(err) => return Err(make_xml_error(activation, err)),
};
match &event { match &event {
Event::Start(bs) => { Event::Start(bs) => {

View File

@ -287,6 +287,20 @@ pub fn make_error_1065<'gc>(
} }
} }
#[inline(never)]
#[cold]
pub fn make_error_1085<'gc>(activation: &mut Activation<'_, 'gc>, tag: &str) -> Error<'gc> {
let err = type_error(
activation,
&format!("Error #1085: The element type \"{tag}\" must be terminated by the matching end-tag \"</{tag}>\"."),
1085,
);
match err {
Ok(err) => Error::AvmError(err),
Err(err) => err,
}
}
#[inline(never)] #[inline(never)]
#[cold] #[cold]
pub fn make_error_1086<'gc>(activation: &mut Activation<'_, 'gc>, method_name: &str) -> Error<'gc> { pub fn make_error_1086<'gc>(activation: &mut Activation<'_, 'gc>, method_name: &str) -> Error<'gc> {