summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-10-24 13:14:31 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-10-24 13:14:31 +0800
commit6810257923b2c7d4cd39c026c0a0e8c280d77d97 (patch)
tree4e5787815992a54b5069ed0082fd6ad48c0b7b03 /src
parent653e79c3e0515cc33b9915973c8e43021f8f2a87 (diff)
fix: verify out of bound slice poshash_chain
Diffstat (limited to 'src')
-rw-r--r--src/hash_chain.rs38
-rw-r--r--src/ui.rs3
2 files changed, 24 insertions, 17 deletions
diff --git a/src/hash_chain.rs b/src/hash_chain.rs
index e3a743c..db3e4e2 100644
--- a/src/hash_chain.rs
+++ b/src/hash_chain.rs
@@ -59,13 +59,19 @@ impl<T: Encode> HashChain<T> {
.iter()
.position(|x| x.0 == until_hash)
.unwrap();
- self.data[pos..=1]
+
+ self.data
.iter()
- .enumerate()
- .all(|(prev_hash, (pred_prev_hash, _))| {
- let prev_hash = Self::hash_o_item(&self.data[prev_hash - 1]);
- prev_hash == *pred_prev_hash
+ .take(pos + 1)
+ .try_fold(Vec::<u8>::new(), |prev, (hash, val)| {
+ let expected = Self::hash_item((&prev, val));
+ if *hash == expected {
+ Ok(expected)
+ } else {
+ Err(())
+ }
})
+ .is_ok()
}
pub fn rehash(&mut self, from_hash: &[u8]) {
@@ -75,20 +81,18 @@ impl<T: Encode> HashChain<T> {
.position(|x| x.0 == *from_hash)
.unwrap();
- let prev_hashes: Vec<_> = (pos..self
- .data
- .len())
- .map(|i| Self::hash_o_item(&self.data[i - 1]))
- .collect();
-
- self.data[pos..]
+ let mut prev = self.data[pos]
+ .0
+ .clone();
+ self.data
.iter_mut()
- .enumerate()
- .map(|(idx, item)| (item, prev_hashes[idx].clone()))
- .for_each(|((pred_prev_hash, _), prev_hash)| {
- if prev_hash != *pred_prev_hash {
- *pred_prev_hash = prev_hash;
+ .skip(pos + 1)
+ .for_each(|(hash, val)| {
+ let expected = Self::hash_item((&prev, val));
+ if *hash != expected {
+ *hash = expected.clone();
}
+ prev = expected;
});
}
diff --git a/src/ui.rs b/src/ui.rs
index f11eaaa..0321790 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -25,6 +25,9 @@ impl Ui {
let cmd: Vec<&str> = cmd
.split_whitespace()
.collect();
+ if cmd.is_empty() {
+ return None;
+ }
if cmd[0] == "trans" {
let trans = Transaction::new(
self.me,