Skip to content

Commit

Permalink
feat: added crate truncation error check
Browse files Browse the repository at this point in the history
  • Loading branch information
Hirevo committed May 20, 2023
1 parent b94822b commit f296205
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
20 changes: 20 additions & 0 deletions crates/alexandrie/src/api/crates/publish.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::HashMap;
use std::io::Read;
use std::path::PathBuf;
use std::pin::pin;

use async_std::io::prelude::*;

Expand Down Expand Up @@ -171,6 +172,21 @@ fn link_badges(
Ok(())
}

/// Checks whether the passed-in reader has ended (meaning it has reached EOF).
///
/// This function tests for this by attempting to read one more byte from the passed-in reader.
/// Therefore, the reader should not be used after having called this function, because that one byte
/// will be missing from the output.
async fn has_reader_ended<R>(reader: R) -> std::io::Result<bool>
where
R: async_std::io::Read,
{
pin!(reader)
.read(&mut [0])
.await
.map(|bytes_read| bytes_read == 0)
}

/// Route to publish a new crate (used by `cargo publish`).
pub(crate) async fn put(mut req: Request<State>) -> tide::Result {
let state = req.state().clone();
Expand All @@ -191,6 +207,10 @@ pub(crate) async fn put(mut req: Request<State>) -> tide::Result {
.take(max_crate_size)
.read_to_end(&mut bytes)
.await?;

if !has_reader_ended(&mut req).await? {
return Err(Error::from(AlexError::CrateTooLarge { max_crate_size }).into());
}
} else {
(&mut req).read_to_end(&mut bytes).await?;
}
Expand Down
8 changes: 8 additions & 0 deletions crates/alexandrie/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ pub enum AlexError {
/// The list of missing query parameters.
missing_params: &'static [&'static str],
},
/// The uploaded crate is larger than the maximum allowed crate size.
#[error(
"uploaded crate is larger than the maximum allowed crate size of {max_crate_size} bytes"
)]
CrateTooLarge {
/// The maximum allowed crate size (in bytes).
max_crate_size: u64,
},
}

// impl IntoResponse for Error {
Expand Down

0 comments on commit f296205

Please sign in to comment.