发布资料摘要给图片字节加长度前缀
- metadata_digest 逐张先写 u64 长度再写字节,分片边界进入摘要 - 否则「封面 [1,2]+截图 [3]」与「封面 [1]+截图 [2,3]」摘要相同,本地幂等账本会误判重放 - 补分片不变性断言
This commit is contained in:
@@ -446,6 +446,9 @@ fn metadata_digest(
|
||||
hasher.update(&bytes);
|
||||
hasher.update(price_mud_points.to_le_bytes());
|
||||
for image in media.cover.iter().chain(media.screenshots.iter()) {
|
||||
// 逐张带长度前缀:图片之间没有分隔符,只串裸字节会让「封面 [1,2] + 截图 [3]」与
|
||||
// 「封面 [1] + 截图 [2,3]」撞成同一摘要,本地幂等账本就会把改过的图当成重放。
|
||||
hasher.update((image.bytes.len() as u64).to_le_bytes());
|
||||
hasher.update(&image.bytes);
|
||||
}
|
||||
Ok(format!("{:x}", hasher.finalize()))
|
||||
@@ -1672,6 +1675,31 @@ mod tests {
|
||||
metadata_digest(&metadata, 0, &media).expect("changed"),
|
||||
first
|
||||
);
|
||||
// 分片边界也要进摘要:两组图裸字节串起来相同,但封面/截图的切分不同。
|
||||
let split_a = PublishMedia {
|
||||
cover: Some(DraftImage {
|
||||
bytes: vec![1, 2],
|
||||
content_type: "image/png",
|
||||
}),
|
||||
screenshots: vec![DraftImage {
|
||||
bytes: vec![3],
|
||||
content_type: "image/png",
|
||||
}],
|
||||
};
|
||||
let split_b = PublishMedia {
|
||||
cover: Some(DraftImage {
|
||||
bytes: vec![1],
|
||||
content_type: "image/png",
|
||||
}),
|
||||
screenshots: vec![DraftImage {
|
||||
bytes: vec![2, 3],
|
||||
content_type: "image/png",
|
||||
}],
|
||||
};
|
||||
assert_ne!(
|
||||
metadata_digest(&metadata, 0, &split_a).expect("split a"),
|
||||
metadata_digest(&metadata, 0, &split_b).expect("split b")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user