Skip to content

Commit c644565

Browse files
committed
basic index file checksum verification (#293)
1 parent ea169a6 commit c644565

File tree

5 files changed

+79
-32
lines changed

5 files changed

+79
-32
lines changed

Diff for: git-index/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal-testing-to-avoid-being-run-by-cargo-test-all = []
3030
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
3131

3232
[dependencies]
33-
git-features = { version = "^0.19.1", path = "../git-features", features = ["rustsha1"] }
33+
git-features = { version = "^0.19.1", path = "../git-features", features = ["rustsha1", "progress"] }
3434
git-hash = { version = "^0.9.1", path = "../git-hash" }
3535
git-bitmap = { version = "^0.0.1", path = "../git-bitmap" }
3636

Diff for: git-index/src/access.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use crate::{extension, Entry, State, Version};
2+
3+
impl State {
4+
pub fn version(&self) -> Version {
5+
self.version
6+
}
7+
8+
pub fn entries(&self) -> &[Entry] {
9+
&self.entries
10+
}
11+
pub fn tree(&self) -> Option<&extension::Tree> {
12+
self.tree.as_ref()
13+
}
14+
pub fn link(&self) -> Option<&extension::Link> {
15+
self.link.as_ref()
16+
}
17+
pub fn resolve_undo(&self) -> Option<&extension::resolve_undo::Paths> {
18+
self.resolve_undo.as_ref()
19+
}
20+
pub fn untracked(&self) -> Option<&extension::UntrackedCache> {
21+
self.untracked.as_ref()
22+
}
23+
pub fn fs_monitor(&self) -> Option<&extension::FsMonitor> {
24+
self.fs_monitor.as_ref()
25+
}
26+
}

Diff for: git-index/src/file.rs

+42
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,45 @@ pub mod init {
6464
}
6565
}
6666
}
67+
68+
mod verify {
69+
use crate::File;
70+
use std::sync::atomic::AtomicBool;
71+
72+
pub mod error {
73+
use quick_error::quick_error;
74+
75+
quick_error! {
76+
#[derive(Debug)]
77+
pub enum Error {
78+
Io(err: std::io::Error) {
79+
display("Could not read index file to generate hash")
80+
source(err)
81+
from()
82+
}
83+
ChecksumMismatch { actual: git_hash::ObjectId, expected: git_hash::ObjectId }{
84+
display("Index checksum should have been {}, but was {}", expected, actual)
85+
}
86+
}
87+
}
88+
}
89+
pub use error::Error;
90+
91+
impl File {
92+
pub fn verify_integrity(&self) -> Result<(), Error> {
93+
let num_bytes_to_hash = self.path.metadata()?.len() - self.checksum.as_bytes().len() as u64;
94+
let should_interrupt = AtomicBool::new(false);
95+
let actual = git_features::hash::bytes_of_file(
96+
&self.path,
97+
num_bytes_to_hash as usize,
98+
self.checksum.kind(),
99+
&mut git_features::progress::Discard,
100+
&should_interrupt,
101+
)?;
102+
(actual == self.checksum).then(|| ()).ok_or(Error::ChecksumMismatch {
103+
actual,
104+
expected: self.checksum,
105+
})
106+
}
107+
}
108+
}

Diff for: git-index/src/lib.rs

+1-28
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,7 @@ pub mod extension;
1111

1212
pub mod entry;
1313

14-
mod access {
15-
use crate::{extension, Entry, State, Version};
16-
17-
impl State {
18-
pub fn version(&self) -> Version {
19-
self.version
20-
}
21-
22-
pub fn entries(&self) -> &[Entry] {
23-
&self.entries
24-
}
25-
pub fn tree(&self) -> Option<&extension::Tree> {
26-
self.tree.as_ref()
27-
}
28-
pub fn link(&self) -> Option<&extension::Link> {
29-
self.link.as_ref()
30-
}
31-
pub fn resolve_undo(&self) -> Option<&extension::resolve_undo::Paths> {
32-
self.resolve_undo.as_ref()
33-
}
34-
pub fn untracked(&self) -> Option<&extension::UntrackedCache> {
35-
self.untracked.as_ref()
36-
}
37-
pub fn fs_monitor(&self) -> Option<&extension::FsMonitor> {
38-
self.fs_monitor.as_ref()
39-
}
40-
}
41-
}
14+
mod access;
4215

4316
pub mod decode;
4417

Diff for: git-index/tests/index/file/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ mod init {
77

88
fn loose_file(name: &str) -> git_index::File {
99
let path = git_testtools::fixture_path(Path::new("loose_index").join(name).with_extension("git-index"));
10-
git_index::File::at(path, git_index::decode::Options::default()).unwrap()
10+
let file = git_index::File::at(path, git_index::decode::Options::default()).unwrap();
11+
file.verify_integrity().unwrap();
12+
file
1113
}
1214
fn file(name: &str) -> git_index::File {
13-
git_index::File::at(crate::fixture_path(name), git_index::decode::Options::default()).unwrap()
15+
let file = git_index::File::at(crate::fixture_path(name), git_index::decode::Options::default()).unwrap();
16+
file.verify_integrity().unwrap();
17+
file
1418
}
1519
fn file_opt(name: &str, opts: git_index::decode::Options) -> git_index::File {
16-
git_index::File::at(crate::fixture_path(name), opts).unwrap()
20+
let file = git_index::File::at(crate::fixture_path(name), opts).unwrap();
21+
file.verify_integrity().unwrap();
22+
file
1723
}
1824

1925
#[test]

0 commit comments

Comments
 (0)