Skip to content

Avoid panics when failing to parse zip files #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions gitlab-runner/src/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{
path::Path,
};

use zip::read::ZipFile;
use zip::{read::ZipFile, result::ZipResult};

/// A file in a gitlab artifact
///
Expand Down Expand Up @@ -35,15 +35,6 @@ impl Read for ArtifactFile<'_> {
pub(crate) trait ReadSeek: Read + Seek {}
impl<T> ReadSeek for T where T: Read + Seek {}

impl<T> From<T> for Artifact
where
T: Send + Read + Seek + 'static,
{
fn from(data: T) -> Self {
Artifact::new(Box::new(data))
}
}

/// An artifact downloaded from gitlab
///
/// The artifact holds a set of files which can be read out one by one
Expand All @@ -52,10 +43,9 @@ pub struct Artifact {
}

impl Artifact {
pub(crate) fn new(data: Box<dyn ReadSeek + Send>) -> Self {
//let reader = std::io::Cursor::new(data);
let zip = zip::ZipArchive::new(data).unwrap();
Self { zip }
pub(crate) fn new(data: Box<dyn ReadSeek + Send>) -> ZipResult<Self> {
let zip = zip::ZipArchive::new(data)?;
Ok(Self { zip })
}

/// Iterator of the files names inside the artifacts
Expand Down
3 changes: 3 additions & 0 deletions gitlab-runner/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::time::Duration;
use thiserror::Error;
use tokio::io::{AsyncWrite, AsyncWriteExt};
use url::Url;
use zip::result::ZipError;

fn deserialize_null_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
Expand Down Expand Up @@ -196,6 +197,8 @@ pub enum Error {
Request(#[from] reqwest::Error),
#[error("Failed to write to destination {0}")]
WriteFailure(#[source] futures::io::Error),
#[error("Failed to parse zip file: {0}")]
ZipFile(#[from] ZipError),
#[error("Empty trace")]
EmptyTrace,
}
Expand Down
6 changes: 4 additions & 2 deletions gitlab-runner/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,15 @@ impl ArtifactCache {
async fn get(&self, id: u64) -> Result<Option<Artifact>, ClientError> {
if let Some(data) = self.lookup(id) {
match data {
CacheData::MemoryBacked(m) => Ok(Some(Artifact::from(std::io::Cursor::new(m)))),
CacheData::MemoryBacked(m) => {
Ok(Some(Artifact::new(Box::new(std::io::Cursor::new(m)))?))
}
CacheData::FileBacked(p) => {
let f = tokio::fs::File::open(p)
.await
.map_err(ClientError::WriteFailure)?;
// Always succeeds as no operations have been started
Ok(Some(Artifact::from(f.try_into_std().unwrap())))
Ok(Some(Artifact::new(Box::new(f.try_into_std().unwrap()))?))
}
}
} else {
Expand Down