Skip to content

Commit

Permalink
Merge pull request #376 from saks/encrypted_xlsx
Browse files Browse the repository at this point in the history
Fixes #102
  • Loading branch information
tafia authored Dec 12, 2023
2 parents 1f95e96 + 78d2943 commit 7342e2d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/xlsx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub enum XlsxError {
},
/// Cell error
CellError(String),
/// Workbook is password protected
Password,
}

from_err!(std::io::Error, XlsxError, Io);
Expand Down Expand Up @@ -127,6 +129,7 @@ impl std::fmt::Display for XlsxError {
XlsxError::Unexpected(e) => write!(f, "{}", e),
XlsxError::Unrecognized { typ, val } => write!(f, "Unrecognized {}: {}", typ, val),
XlsxError::CellError(e) => write!(f, "Unsupported cell error value '{}'", e),
XlsxError::Password => write!(f, "Workbook is password protected"),
}
}
}
Expand Down Expand Up @@ -775,7 +778,9 @@ where
impl<RS: Read + Seek> Reader<RS> for Xlsx<RS> {
type Error = XlsxError;

fn new(reader: RS) -> Result<Self, XlsxError> {
fn new(mut reader: RS) -> Result<Self, XlsxError> {
check_for_password_protected(&mut reader)?;

let mut xlsx = Xlsx {
zip: ZipArchive::new(reader)?,
strings: Vec::new(),
Expand Down Expand Up @@ -1270,6 +1275,19 @@ fn read_string(
}
}

fn check_for_password_protected<RS: Read + Seek>(reader: &mut RS) -> Result<(), XlsxError> {
let offset_end = reader.seek(std::io::SeekFrom::End(0))? as usize;
reader.seek(std::io::SeekFrom::Start(0))?;

if let Ok(cfb) = crate::cfb::Cfb::new(reader, offset_end) {
if cfb.has_directory("EncryptedPackage") {
return Err(XlsxError::Password);
}
};

Ok(())
}

#[test]
fn test_dimensions() {
assert_eq!(get_row_column(b"A1").unwrap(), (0, 0));
Expand Down
Binary file added tests/pass_protected.xlsx
Binary file not shown.
15 changes: 15 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,21 @@ fn any_sheets_ods() {
);
}

#[test]
fn issue_102() {
setup();

let path = format!("{}/tests/pass_protected.xlsx", env!("CARGO_MANIFEST_DIR"));

assert!(
matches!(
open_workbook::<Xlsx<_>, std::string::String>(path),
Err(calamine::XlsxError::Password)
),
"Is expeced to return XlsxError::Password error"
);
}

#[test]
fn issue_374() {
let path = format!("{}/tests/biff5_write.xls", env!("CARGO_MANIFEST_DIR"));
Expand Down

0 comments on commit 7342e2d

Please sign in to comment.