feat(peer): validate manifests before download mutation
Why: - Remote and UI-echoed file descriptions could reach transaction and storage code one entry at a time, so a hostile late path could mutate earlier files. - Per-file consensus also accepted malformed peer lists and let duplicate rows inflate a source's vote. What: - Add a complete protocol-7 manifest adapter with catalog-root confinement, portable path and alias rules, reserved-path protection, shape and size caps, symlink/reparse inspection, and zero-mutation tests. - Keep download selection in the peer core, validate every peer manifest before consensus, and pass only the validated manifest into storage/orchestration. - Canonicalize locally advertised paths, cap exact chunk receives, and preserve the local-only install fast path. - Record the chosen safety limits and follow-up ownership/catalog decisions. Test Plan: - just clippy - just test - just frontend-test - just build - just fmt (Rust/TOML/Prettier completed; rumdl reports 39 pre-existing issues) - git diff --cached --check
This commit is contained in:
12 files changed
+1376
-137
No files matched your search
@@ -238,14 +238,10 @@ pub enum PeerCommand {
|
||||
/// Request the latest peer-advertised file details for an update.
|
||||
FetchLatestFromPeers { id: String },
|
||||
/// Download game files.
|
||||
DownloadGameFiles {
|
||||
id: String,
|
||||
file_descriptions: Vec<GameFileDescription>,
|
||||
},
|
||||
DownloadGameFiles { id: String },
|
||||
/// Download game files with an explicit install policy.
|
||||
DownloadGameFilesWithOptions {
|
||||
id: String,
|
||||
file_descriptions: Vec<GameFileDescription>,
|
||||
install_after_download: bool,
|
||||
},
|
||||
/// Stream archive-expanded bytes directly into `local/` without keeping root archives.
|
||||
@@ -458,26 +454,15 @@ async fn handle_peer_commands(
|
||||
handle_get_game_command(ctx, tx_notify_ui, id, GameDetailSource::LatestPeersOnly)
|
||||
.await;
|
||||
}
|
||||
PeerCommand::DownloadGameFiles {
|
||||
id,
|
||||
file_descriptions,
|
||||
} => {
|
||||
handle_download_game_files_command(ctx, tx_notify_ui, id, file_descriptions, true)
|
||||
.await;
|
||||
PeerCommand::DownloadGameFiles { id } => {
|
||||
handle_download_game_files_command(ctx, tx_notify_ui, id, true).await;
|
||||
}
|
||||
PeerCommand::DownloadGameFilesWithOptions {
|
||||
id,
|
||||
file_descriptions,
|
||||
install_after_download,
|
||||
} => {
|
||||
handle_download_game_files_command(
|
||||
ctx,
|
||||
tx_notify_ui,
|
||||
id,
|
||||
file_descriptions,
|
||||
install_after_download,
|
||||
)
|
||||
.await;
|
||||
handle_download_game_files_command(ctx, tx_notify_ui, id, install_after_download)
|
||||
.await;
|
||||
}
|
||||
PeerCommand::StreamInstallGame { id } => {
|
||||
handlers::handle_stream_install_game_command(ctx, tx_notify_ui, id).await;
|
||||
|
||||
Reference in new issue
Block a user