Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 17 additions & 24 deletions src/xls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl std::fmt::Display for XlsError {
typ,
} => write!(
f,
"Invalid {typ} length, expected {expected} maximum, found {found}",
"Invalid {typ} length, expected at least {expected}, found {found}",
),
XlsError::ContinueRecordTooShort => write!(
f,
Expand Down Expand Up @@ -397,9 +397,7 @@ impl<RS: Read + Seek> Xls<RS> {
0x00EB => {
// MsoDrawingGroup
draw_group.extend(r.data);
if let Some(cont) = r.cont {
draw_group.extend(cont.iter().flat_map(|v| *v));
}
draw_group.extend(r.cont.iter().flat_map(|v| *v));
}
0x000A => break, // EOF,
_ => (),
Expand Down Expand Up @@ -933,10 +931,9 @@ fn parse_xf(r: &Record<'_>) -> Result<u16, XlsError> {
Ok(read_u16(&r.data[2..]))
}

/// Decode Format
/// Decode Format [MS-XLS 2.4.126]
///
/// See: <https://learn.microsoft.com/ru-ru/openspecs/office_file_formats/ms-xls/300280fd-e4fe-4675-a924-4d383af48d3b>
/// 2.4.126
fn parse_format(
r: &mut Record<'_>,
encoding: &XlsEncoding,
Expand All @@ -959,13 +956,17 @@ fn parse_format(
Ok((ifmt, detect_custom_number_format(&s)))
}

/// Decode `XLUnicodeRichExtendedString`.
/// Decode `XLUnicodeRichExtendedString` [MS-XLS 2.5.293].
///
/// See: <https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/173d9f51-e5d3-43da-8de2-be7f22e119b9>
fn read_rich_extended_string(
r: &mut Record<'_>,
encoding: &XlsEncoding,
) -> Result<String, XlsError> {
if r.data.is_empty() {
// spec violation: at very least cch and flags should be present
return Ok(String::new());
}
if r.data.len() < 3 {
return Err(XlsError::Len {
typ: "rich extended string",
Expand Down Expand Up @@ -1041,21 +1042,16 @@ fn read_unicode_string_no_cch(encoding: &XlsEncoding, buf: &[u8], len: &usize, s
struct Record<'a> {
typ: u16,
data: &'a [u8],
cont: Option<Vec<&'a [u8]>>,
cont: Vec<&'a [u8]>,
}

impl<'a> Record<'a> {
fn continue_record(&mut self) -> bool {
match self.cont {
None => false,
Some(ref mut v) => {
if v.is_empty() {
false
} else {
self.data = v.remove(0);
true
}
}
if self.cont.is_empty() {
false
} else {
self.data = self.cont.remove(0);
true
}
}

Expand Down Expand Up @@ -1120,8 +1116,8 @@ impl<'a> Iterator for RecordIter<'a> {
let d = &data[4..];

// Append next record data if it is a Continue record
let cont = if next.len() > 4 && read_u16(next) == 0x003C {
let mut cont = Vec::new();
let mut cont = Vec::new();
if next.len() > 4 && read_u16(next) == 0x003C {
while self.stream.len() > 4 && read_u16(self.stream) == 0x003C {
len = read_u16(&self.stream[2..]) as usize;
if self.stream.len() < len + 4 {
Expand All @@ -1131,10 +1127,7 @@ impl<'a> Iterator for RecordIter<'a> {
cont.push(&sp.0[4..]);
self.stream = sp.1;
}
Some(cont)
} else {
None
};
}

Some(Ok(Record {
typ: t,
Expand Down