Skip to content

Commit d6c4606

Browse files
committed
bump v0.27.0
- fix (xls): Invalid formats parsing - feat (xls): add one more Error variant related to formatting - fix: Always parse string cell as string - refactor: bump dependencies - fix: pin zip crate to 2.5.* - fix (xlsx): check 'closing' tag name with more prefixes
1 parent 386a745 commit d6c4606

File tree

3 files changed

+36
-20
lines changed

3 files changed

+36
-20
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "calamine"
3-
version = "0.26.1"
3+
version = "0.27.0"
44
authors = ["Johann Tuffe <[email protected]>"]
55
repository = "https://github.com/tafia/calamine"
66
documentation = "https://docs.rs/calamine"

Changelog.md

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010

1111
## Unreleased
1212

13+
## 0.27.0 (2025-04-22)
14+
15+
- fix (xls): Invalid formats parsing
16+
- feat (xls): add one more Error variant related to formatting
17+
- fix: Always parse string cell as string
18+
- refactor: bump dependencies
19+
- fix: pin zip crate to 2.5.*
20+
- fix (xlsx): check 'closing' tag name with more prefixes
21+
1322
## 0.26.1 (2024-10-10)
1423

1524
- fix: sparse celle expect 0 index rows, even when using `header_row`

src/xls.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ pub enum XlsError {
7272
Art(&'static str),
7373
/// Worksheet not found
7474
WorksheetNotFound(String),
75+
/// Invalid iFmt value
76+
InvalidFormat {
77+
/// iFmt value, See 2.4.126 Format
78+
ifmt: u16,
79+
},
7580
}
7681

7782
from_err!(std::io::Error, XlsError, Io);
@@ -109,6 +114,7 @@ impl std::fmt::Display for XlsError {
109114
#[cfg(feature = "picture")]
110115
XlsError::Art(s) => write!(f, "Invalid art record '{s}'"),
111116
XlsError::WorksheetNotFound(name) => write!(f, "Worksheet '{name}' not found"),
117+
XlsError::InvalidFormat { ifmt } => write!(f, "Invalid ifmt value: '{ifmt}'"),
112118
}
113119
}
114120
}
@@ -339,12 +345,12 @@ impl<RS: Read + Seek> Xls<RS> {
339345
}
340346
}
341347
// 2.4.126 FORMATTING
342-
0x041E => {
343-
let Ok((idx, format)) = parse_format(&mut r, &encoding) else {
344-
continue;
345-
};
346-
formats.insert(idx, format);
347-
}
348+
0x041E => match parse_format(&mut r, &encoding, biff) {
349+
Ok((idx, format)) => {
350+
formats.insert(idx, format);
351+
}
352+
Err(e) => log::warn!("{e}"),
353+
},
348354
// XFS
349355
0x00E0 => {
350356
xfs.push(parse_xf(&r)?);
@@ -913,25 +919,26 @@ fn parse_xf(r: &Record<'_>) -> Result<u16, XlsError> {
913919
///
914920
/// See: https://learn.microsoft.com/ru-ru/openspecs/office_file_formats/ms-xls/300280fd-e4fe-4675-a924-4d383af48d3b
915921
/// 2.4.126
916-
fn parse_format(r: &mut Record<'_>, encoding: &XlsEncoding) -> Result<(u16, CellFormat), XlsError> {
917-
if r.data.len() < 5 {
922+
fn parse_format(
923+
r: &mut Record<'_>,
924+
encoding: &XlsEncoding,
925+
biff: Biff,
926+
) -> Result<(u16, CellFormat), XlsError> {
927+
if r.data.len() < 2 {
918928
return Err(XlsError::Len {
919929
typ: "format",
920-
expected: 5,
930+
expected: 2,
921931
found: r.data.len(),
922932
});
923933
}
934+
let ifmt = read_u16(r.data);
935+
match ifmt {
936+
5..=8 | 23..=26 | 41..=44 | 63..=66 | 164..=382 => (),
937+
_ => return Err(XlsError::InvalidFormat { ifmt }),
938+
}
924939

925-
let idx = read_u16(r.data);
926-
927-
// TODO: check if this can be replaced with parse_string()
928-
let cch = read_u16(&r.data[2..]) as usize;
929-
let high_byte = r.data[4] & 0x1 != 0;
930-
r.data = &r.data[5..];
931-
let mut s = String::with_capacity(cch);
932-
encoding.decode_to(r.data, cch, &mut s, Some(high_byte));
933-
934-
Ok((idx, detect_custom_number_format(&s)))
940+
let s = parse_string(&r.data[2..], encoding, biff)?;
941+
Ok((ifmt, detect_custom_number_format(&s)))
935942
}
936943

937944
/// Decode XLUnicodeRichExtendedString.

0 commit comments

Comments
 (0)