From: Lennart Poettering Date: Wed, 5 Nov 2025 15:58:09 +0000 (+0100) Subject: pull-job: optionally take expected content length and compare it with what we are... X-Git-Tag: v259-rc1~127^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cb1caab98ee495df63ade4095e96ea07eae05843;p=thirdparty%2Fsystemd.git pull-job: optionally take expected content length and compare it with what we are downloading --- diff --git a/src/import/pull-job.c b/src/import/pull-job.c index 6c7b328a0c4..9459a89ceaa 100644 --- a/src/import/pull-job.c +++ b/src/import/pull-job.c @@ -93,6 +93,7 @@ static int pull_job_restart(PullJob *j, const char *new_url) { j->etag_exists = false; j->mtime = 0; j->checksum = mfree(j->checksum); + j->expected_content_length = UINT64_MAX; curl_glue_remove_and_free(j->glue, j->curl); j->curl = NULL; @@ -114,6 +115,15 @@ static int pull_job_restart(PullJob *j, const char *new_url) { return 0; } +static uint64_t pull_job_content_length_effective(PullJob *j) { + assert(j); + + if (j->expected_content_length != UINT64_MAX) + return j->expected_content_length; + + return j->content_length; +} + void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) { PullJob *j = NULL; char *scheme = NULL; @@ -214,8 +224,9 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) { goto finish; } - if (j->content_length != UINT64_MAX && - j->content_length != j->written_compressed) { + uint64_t cl = pull_job_content_length_effective(j); + if (cl != UINT64_MAX && + cl != j->written_compressed) { r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Download truncated."); goto finish; } @@ -374,8 +385,9 @@ static int pull_job_write_compressed(PullJob *j, void *p, size_t sz) { if (j->written_compressed + sz > j->compressed_max) return log_error_errno(SYNTHETIC_ERRNO(EFBIG), "File overly large, refusing."); - if (j->content_length != UINT64_MAX && - j->written_compressed + sz > j->content_length) + uint64_t cl = pull_job_content_length_effective(j); + if (cl != UINT64_MAX && + j->written_compressed + sz > cl) return log_error_errno(SYNTHETIC_ERRNO(EFBIG), "Content length incorrect."); @@ -589,6 +601,12 @@ static size_t pull_job_header_callback(void *contents, size_t size, size_t nmemb goto fail; } + if (j->expected_content_length != UINT64_MAX && + j->expected_content_length != j->content_length) { + r = log_error_errno(SYNTHETIC_ERRNO(EPROTO), "Content does not have expected size."); + goto fail; + } + log_info("Downloading %s for %s.", FORMAT_BYTES(j->content_length), j->url); } @@ -691,6 +709,7 @@ int pull_job_new( .url = TAKE_PTR(u), .offset = UINT64_MAX, .sync = true, + .expected_content_length = UINT64_MAX, }; *ret = TAKE_PTR(j); diff --git a/src/import/pull-job.h b/src/import/pull-job.h index b39e11929fc..34156e9dd6f 100644 --- a/src/import/pull-job.h +++ b/src/import/pull-job.h @@ -58,6 +58,8 @@ typedef struct PullJob { uint64_t uncompressed_max; uint64_t compressed_max; + uint64_t expected_content_length; + uint8_t *payload; size_t payload_size;