text_reader: binary nodes are not required to specify the size of the binary data

This commit is contained in:
Matt Bilker
2019-10-24 17:52:00 +00:00
parent b8bf1c1bfb
commit a09bb682f4

View File

@@ -18,7 +18,7 @@ pub struct TextXmlReader<'a> {
xml_reader: Reader<&'a [u8]>,
encoding: EncodingType,
stack: Vec<(NodeCollection, usize, usize)>,
stack: Vec<(NodeCollection, usize, Option<usize>)>,
}
impl<'a> TextXmlReader<'a> {
@@ -61,10 +61,10 @@ impl<'a> TextXmlReader<'a> {
Ok(NodeDefinition::with_data(self.encoding, node_type, data))
}
fn parse_attributes(&self, attrs: Attributes<'a>) -> Result<(StandardType, usize, usize, Vec<NodeDefinition>)> {
fn parse_attributes(&self, attrs: Attributes<'a>) -> Result<(StandardType, usize, Option<usize>, Vec<NodeDefinition>)> {
let mut node_type = None;
let mut count = 0;
let mut size = 0;
let mut size = None;
let mut attributes = Vec::new();
for attr in attrs {
@@ -88,9 +88,12 @@ impl<'a> TextXmlReader<'a> {
count = num_count as usize;
} else if attr.key == b"__size" {
let value = str::from_utf8(&*value).context(KbinErrorKind::Utf8)?;
let value = str::from_utf8(&*value)
.context(KbinErrorKind::Utf8)?
.parse::<usize>()
.context(KbinErrorKind::StringParse("binary size"))?;
size = value.parse::<usize>().context(KbinErrorKind::StringParse("binary size"))?;
size = Some(value);
} else {
let definition = self.parse_attribute(attr.key, &value)?;
attributes.push(definition);
@@ -114,7 +117,7 @@ impl<'a> TextXmlReader<'a> {
Ok((node_type, count, size, attributes))
}
fn handle_start(&self, e: BytesStart) -> Result<(NodeCollection, usize, usize)> {
fn handle_start(&self, e: BytesStart) -> Result<(NodeCollection, usize, Option<usize>)> {
let (node_type, count, size, attributes) = self.parse_attributes(e.attributes())?;
// Stub the value for now, handle with `Event::Text`.
@@ -138,7 +141,7 @@ impl<'a> TextXmlReader<'a> {
Ok((collection, count, size))
}
fn handle_text(event: BytesText, definition: &mut NodeDefinition, count: usize, size: usize) -> Result<()> {
fn handle_text(event: BytesText, definition: &mut NodeDefinition, count: usize, size: Option<usize>) -> Result<()> {
let data = event.unescaped().context(KbinErrorKind::Utf8)?;
let data = match definition.node_type {
StandardType::String |
@@ -156,9 +159,11 @@ impl<'a> TextXmlReader<'a> {
let value = Value::from_string(definition.node_type, text, definition.is_array, count)?;
if let Value::Binary(data) = &value {
// The read number of bytes must match the size attribute
if data.len() != size {
return Err(KbinErrorKind::InvalidState.into());
// The read number of bytes must match the size attribute, if set
if let Some(size) = size {
if data.len() != size {
return Err(KbinErrorKind::InvalidState.into());
}
}
}
@@ -210,7 +215,7 @@ impl<'a> TextXmlReader<'a> {
Ok(Event::Empty(e)) => {
let (collection, count, size) = self.handle_start(e)?;
assert!(count == 0, "empty node should not signal an array");
assert!(size == 0, "empty node should not signal binary data");
assert!(size.is_none() || size == Some(0), "empty node should not signal binary data");
if let Some((ref mut parent_collection, _count, _size)) = self.stack.last_mut() {
parent_collection.children_mut().push_back(collection);