Skip to content

Commit

Permalink
iso9660.rs: added an error check
Browse files Browse the repository at this point in the history
Added an "Incomplete download of ISO image" error check to the ISO9660 parser and a following test to verify it.
  • Loading branch information
RishabhSaini committed Jul 12, 2022
1 parent bb5e2b8 commit ac5f48d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Major changes:
Minor changes:

- Add release notes to documentation
- Added an error check for detecting an incomplete ISO image

Internal changes:

Expand Down
34 changes: 32 additions & 2 deletions src/iso9660.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,20 @@ pub struct IsoFs {

impl IsoFs {
pub fn from_file(mut file: fs::File) -> Result<Self> {
let length = file.metadata()?.len();
let descriptors = get_volume_descriptors(&mut file)?;
Ok(Self { descriptors, file })
let iso_fs = IsoFs {
descriptors: descriptors,
file: file,
};
let primary_volume_descriptor = iso_fs.get_primary_volume_descriptor()?;
if u64::from(primary_volume_descriptor.volume_space_size) * ISO9660_SECTOR_SIZE as u64
> length
{
bail!("Incomplete download of the ISO Image");
}

Ok(iso_fs)
}

pub fn as_file(&mut self) -> Result<&mut fs::File> {
Expand Down Expand Up @@ -181,6 +193,7 @@ struct BootVolumeDescriptor {
struct PrimaryVolumeDescriptor {
system_id: String,
volume_id: String,
volume_space_size: u32,
root: Directory,
}

Expand Down Expand Up @@ -298,13 +311,16 @@ impl PrimaryVolumeDescriptor {
parse_iso9660_string(eat(buf, 1), 32, IsoString::StrA).context("parsing system id")?;
let volume_id = // technically should be StrD, but non-compliance is common
parse_iso9660_string(buf, 32, IsoString::StrA).context("parsing volume id")?;
let root = match get_next_directory_record(eat(buf, 156 - 72), 34, true)? {
eat(buf, 8); // Unused field always 0x00
let volume_space_size = buf.get_u32_le();
let root = match get_next_directory_record(eat(buf, 156 - 84), 34, true)? {
Some(DirectoryRecord::Directory(d)) => d,
_ => bail!("failed to parse root directory record from primary descriptor"),
};
Ok(Self {
system_id,
volume_id,
volume_space_size,
root,
})
}
Expand Down Expand Up @@ -554,6 +570,7 @@ fn path_components(s: &str) -> Vec<&str> {
mod tests {
use super::*;

use anyhow::Error;
use std::io::copy;

use tempfile::tempfile;
Expand All @@ -567,8 +584,21 @@ mod tests {
IsoFs::from_file(iso_file).unwrap()
}

fn open_truncated_iso() -> Result<IsoFs, Error> {
let iso_bytes: &[u8] = include_bytes!("../fixtures/iso/synthetic.iso.xz");
let mut decoder = XzDecoder::new(iso_bytes);
let mut iso_file = tempfile().unwrap();
copy(&mut decoder, &mut iso_file).unwrap();
let _output = iso_file.set_len(iso_file.metadata().unwrap().len() / 2);
IsoFs::from_file(iso_file)
}

#[test]
fn test_primary_volume_descriptor() {
assert_eq!(
open_truncated_iso().unwrap_err().to_string(),
"Incomplete download of the ISO Image"
);
let iso = open_iso();
let desc = iso.get_primary_volume_descriptor().unwrap();
assert_eq!(desc.system_id, "system-ID-string");
Expand Down

0 comments on commit ac5f48d

Please sign in to comment.