Skip to content

Commit

Permalink
basic index file checksum verification (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jan 27, 2022
1 parent ea169a6 commit c644565
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 32 deletions.
2 changes: 1 addition & 1 deletion git-index/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal-testing-to-avoid-being-run-by-cargo-test-all = []
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
git-features = { version = "^0.19.1", path = "../git-features", features = ["rustsha1"] }
git-features = { version = "^0.19.1", path = "../git-features", features = ["rustsha1", "progress"] }
git-hash = { version = "^0.9.1", path = "../git-hash" }
git-bitmap = { version = "^0.0.1", path = "../git-bitmap" }

Expand Down
26 changes: 26 additions & 0 deletions git-index/src/access.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::{extension, Entry, State, Version};

impl State {
pub fn version(&self) -> Version {
self.version
}

pub fn entries(&self) -> &[Entry] {
&self.entries
}
pub fn tree(&self) -> Option<&extension::Tree> {
self.tree.as_ref()
}
pub fn link(&self) -> Option<&extension::Link> {
self.link.as_ref()
}
pub fn resolve_undo(&self) -> Option<&extension::resolve_undo::Paths> {
self.resolve_undo.as_ref()
}
pub fn untracked(&self) -> Option<&extension::UntrackedCache> {
self.untracked.as_ref()
}
pub fn fs_monitor(&self) -> Option<&extension::FsMonitor> {
self.fs_monitor.as_ref()
}
}
42 changes: 42 additions & 0 deletions git-index/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,45 @@ pub mod init {
}
}
}

mod verify {
use crate::File;
use std::sync::atomic::AtomicBool;

pub mod error {
use quick_error::quick_error;

quick_error! {
#[derive(Debug)]
pub enum Error {
Io(err: std::io::Error) {
display("Could not read index file to generate hash")
source(err)
from()
}
ChecksumMismatch { actual: git_hash::ObjectId, expected: git_hash::ObjectId }{
display("Index checksum should have been {}, but was {}", expected, actual)
}
}
}
}
pub use error::Error;

impl File {
pub fn verify_integrity(&self) -> Result<(), Error> {
let num_bytes_to_hash = self.path.metadata()?.len() - self.checksum.as_bytes().len() as u64;
let should_interrupt = AtomicBool::new(false);
let actual = git_features::hash::bytes_of_file(
&self.path,
num_bytes_to_hash as usize,
self.checksum.kind(),
&mut git_features::progress::Discard,
&should_interrupt,
)?;
(actual == self.checksum).then(|| ()).ok_or(Error::ChecksumMismatch {
actual,
expected: self.checksum,
})
}
}
}
29 changes: 1 addition & 28 deletions git-index/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,7 @@ pub mod extension;

pub mod entry;

mod access {
use crate::{extension, Entry, State, Version};

impl State {
pub fn version(&self) -> Version {
self.version
}

pub fn entries(&self) -> &[Entry] {
&self.entries
}
pub fn tree(&self) -> Option<&extension::Tree> {
self.tree.as_ref()
}
pub fn link(&self) -> Option<&extension::Link> {
self.link.as_ref()
}
pub fn resolve_undo(&self) -> Option<&extension::resolve_undo::Paths> {
self.resolve_undo.as_ref()
}
pub fn untracked(&self) -> Option<&extension::UntrackedCache> {
self.untracked.as_ref()
}
pub fn fs_monitor(&self) -> Option<&extension::FsMonitor> {
self.fs_monitor.as_ref()
}
}
}
mod access;

pub mod decode;

Expand Down
12 changes: 9 additions & 3 deletions git-index/tests/index/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ mod init {

fn loose_file(name: &str) -> git_index::File {
let path = git_testtools::fixture_path(Path::new("loose_index").join(name).with_extension("git-index"));
git_index::File::at(path, git_index::decode::Options::default()).unwrap()
let file = git_index::File::at(path, git_index::decode::Options::default()).unwrap();
file.verify_integrity().unwrap();
file
}
fn file(name: &str) -> git_index::File {
git_index::File::at(crate::fixture_path(name), git_index::decode::Options::default()).unwrap()
let file = git_index::File::at(crate::fixture_path(name), git_index::decode::Options::default()).unwrap();
file.verify_integrity().unwrap();
file
}
fn file_opt(name: &str, opts: git_index::decode::Options) -> git_index::File {
git_index::File::at(crate::fixture_path(name), opts).unwrap()
let file = git_index::File::at(crate::fixture_path(name), opts).unwrap();
file.verify_integrity().unwrap();
file
}

#[test]
Expand Down

0 comments on commit c644565

Please sign in to comment.