pull-job: optionally take expected content length and compare it with what we are downloading

This commit is contained in:
Lennart Poettering
2025-11-05 16:58:09 +01:00
parent bf51a545a4
commit cb1caab98e
2 changed files with 25 additions and 4 deletions

View File

@@ -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);

View File

@@ -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;