diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-10-11 21:07:18 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-10-11 21:17:24 +0300 |
commit | 1df197e6035ea9826bfedee7d48812e318ba9c7a (patch) | |
tree | 76b8e9de41820755adf209854d06a84a8b5a1988 /contrib/libs/curl/lib/mime.c | |
parent | f9c007ea1b59b960201def74990810b26ecdfd48 (diff) | |
download | ydb-1df197e6035ea9826bfedee7d48812e318ba9c7a.tar.gz |
Revert "Update contrib/libs/curl to 8.10.1" to fix
Revert "Update contrib/libs/curl to 8.10.1"
This reverts commit 428ef806a15515cdaa325530aa8cc6903fac5fb6, reversing
changes made to 40e46e6394df409d1545a3771c8a47a86ed55eac.
Revert "Fix formatting after rXXXXXX"
This reverts commit a73689311a92e195d14136c5a0049ef1e40b1f3e, reversing
changes made to 17980b8756d1f74d3dacddc7ca4945c30f35611c.
commit_hash:5c5194831e5455b61fbee61619066396626beab1
Diffstat (limited to 'contrib/libs/curl/lib/mime.c')
-rw-r--r-- | contrib/libs/curl/lib/mime.c | 364 |
1 files changed, 56 insertions, 308 deletions
diff --git a/contrib/libs/curl/lib/mime.c b/contrib/libs/curl/lib/mime.c index 5df2d68918..b9335e6d37 100644 --- a/contrib/libs/curl/lib/mime.c +++ b/contrib/libs/curl/lib/mime.c @@ -30,7 +30,6 @@ #include "warnless.h" #include "urldata.h" #include "sendf.h" -#include "strdup.h" #if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ !defined(CURL_DISABLE_SMTP) || \ @@ -74,7 +73,6 @@ static curl_off_t encoder_base64_size(curl_mimepart *part); static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, curl_mimepart *part); static curl_off_t encoder_qp_size(curl_mimepart *part); -static curl_off_t mime_size(curl_mimepart *part); static const struct mime_encoder encoders[] = { {"binary", encoder_nop_read, encoder_nop_size}, @@ -92,7 +90,7 @@ static const char base64enc[] = /* Quoted-printable character class table. * * We cannot rely on ctype functions since quoted-printable input data - * is assumed to be ASCII-compatible, even on non-ASCII platforms. */ + * is assumed to be ascii-compatible, even on non-ascii platforms. */ #define QP_OK 1 /* Can be represented by itself. */ #define QP_SP 2 /* Space or tab. */ #define QP_CR 3 /* Carriage return. */ @@ -557,7 +555,7 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, /* On all platforms, input is supposed to be ASCII compatible: for this reason, we use hexadecimal ASCII codes in this function rather than - character constants that can be interpreted as non-ASCII on some + character constants that can be interpreted as non-ascii on some platforms. Preserve ASCII encoding on output too. */ while(st->bufbeg < st->bufend) { size_t len = 1; @@ -819,7 +817,7 @@ static size_t read_part_content(curl_mimepart *part, case MIMEKIND_FILE: if(part->fp && feof(part->fp)) break; /* At EOF. */ - FALLTHROUGH(); + /* FALLTHROUGH */ default: if(part->readfunc) { if(!(part->flags & MIME_FAST_READ)) { @@ -938,7 +936,7 @@ static size_t readback_part(curl_mimepart *part, mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next); break; } - FALLTHROUGH(); + /* FALLTHROUGH */ case MIMESTATE_CURLHEADERS: if(!hdr) mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders); @@ -972,7 +970,7 @@ static size_t readback_part(curl_mimepart *part, fclose(part->fp); part->fp = NULL; } - FALLTHROUGH(); + /* FALLTHROUGH */ case CURL_READFUNC_ABORT: case CURL_READFUNC_PAUSE: case READ_ERROR: @@ -1137,7 +1135,7 @@ static void cleanup_part_content(curl_mimepart *part) part->datasize = (curl_off_t) 0; /* No size yet. */ cleanup_encoder_state(&part->encstate); part->kind = MIMEKIND_NONE; - part->flags &= ~(unsigned int)MIME_FAST_READ; + part->flags &= ~MIME_FAST_READ; part->lastreadstatus = 1; /* Successful read status. */ part->state.state = MIMESTATE_BEGIN; } @@ -1147,7 +1145,7 @@ static void mime_subparts_free(void *ptr) curl_mime *mime = (curl_mime *) ptr; if(mime && mime->parent) { - mime->parent->freefunc = NULL; /* Be sure we will not be called again. */ + mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ } curl_mime_free(mime); @@ -1159,7 +1157,7 @@ static void mime_subparts_unbind(void *ptr) curl_mime *mime = (curl_mime *) ptr; if(mime && mime->parent) { - mime->parent->freefunc = NULL; /* Be sure we will not be called again. */ + mime->parent->freefunc = NULL; /* Be sure we won't be called again. */ cleanup_part_content(mime->parent); /* Avoid dangling pointer in part. */ mime->parent = NULL; } @@ -1186,7 +1184,7 @@ void curl_mime_free(curl_mime *mime) curl_mimepart *part; if(mime) { - mime_subparts_unbind(mime); /* Be sure it is not referenced anymore. */ + mime_subparts_unbind(mime); /* Be sure it's not referenced anymore. */ while(mime->firstpart) { part = mime->firstpart; mime->firstpart = part->nextpart; @@ -1237,7 +1235,6 @@ CURLcode Curl_mime_duppart(struct Curl_easy *data, } break; default: /* Invalid kind: should not occur. */ - DEBUGF(infof(data, "invalid MIMEKIND* attempt")); res = CURLE_BAD_FUNCTION_ARGUMENT; /* Internal error? */ break; } @@ -1354,7 +1351,7 @@ CURLcode curl_mime_name(curl_mimepart *part, const char *name) return CURLE_OK; } -/* Set mime part remote filename. */ +/* Set mime part remote file name. */ CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) { if(!part) @@ -1373,22 +1370,27 @@ CURLcode curl_mime_filename(curl_mimepart *part, const char *filename) /* Set mime part content from memory data. */ CURLcode curl_mime_data(curl_mimepart *part, - const char *ptr, size_t datasize) + const char *data, size_t datasize) { if(!part) return CURLE_BAD_FUNCTION_ARGUMENT; cleanup_part_content(part); - if(ptr) { + if(data) { if(datasize == CURL_ZERO_TERMINATED) - datasize = strlen(ptr); + datasize = strlen(data); - part->data = Curl_memdup0(ptr, datasize); + part->data = malloc(datasize + 1); if(!part->data) return CURLE_OUT_OF_MEMORY; part->datasize = datasize; + + if(datasize) + memcpy(part->data, data, datasize); + part->data[datasize] = '\0'; /* Set a null terminator as sentinel. */ + part->readfunc = mime_mem_read; part->seekfunc = mime_mem_seek; part->freefunc = mime_mem_free; @@ -1413,35 +1415,36 @@ CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename) char *base; struct_stat sbuf; - if(stat(filename, &sbuf)) + if(stat(filename, &sbuf) || access(filename, R_OK)) result = CURLE_READ_ERROR; + + part->data = strdup(filename); + if(!part->data) + result = CURLE_OUT_OF_MEMORY; + + part->datasize = -1; + if(!result && S_ISREG(sbuf.st_mode)) { + part->datasize = filesize(filename, sbuf); + part->seekfunc = mime_file_seek; + } + + part->readfunc = mime_file_read; + part->freefunc = mime_file_free; + part->kind = MIMEKIND_FILE; + + /* As a side effect, set the filename to the current file's base name. + It is possible to withdraw this by explicitly calling + curl_mime_filename() with a NULL filename argument after the current + call. */ + base = strippath(filename); + if(!base) + result = CURLE_OUT_OF_MEMORY; else { - part->data = strdup(filename); - if(!part->data) - result = CURLE_OUT_OF_MEMORY; - else { - part->datasize = -1; - if(S_ISREG(sbuf.st_mode)) { - part->datasize = filesize(filename, sbuf); - part->seekfunc = mime_file_seek; - } + CURLcode res = curl_mime_filename(part, base); - part->readfunc = mime_file_read; - part->freefunc = mime_file_free; - part->kind = MIMEKIND_FILE; - - /* As a side effect, set the filename to the current file's base name. - It is possible to withdraw this by explicitly calling - curl_mime_filename() with a NULL filename argument after the current - call. */ - base = strippath(filename); - if(!base) - result = CURLE_OUT_OF_MEMORY; - else { - result = curl_mime_filename(part, base); - free(base); - } - } + if(res) + result = res; + free(base); } } return result; @@ -1497,7 +1500,7 @@ CURLcode curl_mime_headers(curl_mimepart *part, if(part->flags & MIME_USERHEADERS_OWNER) { if(part->userheaders != headers) /* Allow setting twice the same list. */ curl_slist_free_all(part->userheaders); - part->flags &= ~(unsigned int)MIME_USERHEADERS_OWNER; + part->flags &= ~MIME_USERHEADERS_OWNER; } part->userheaders = headers; if(headers && take_ownership) @@ -1554,7 +1557,7 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part, while(root->parent && root->parent->parent) root = root->parent->parent; if(subparts == root) { - /* cannot add as a subpart of itself. */ + /* Can't add as a subpart of itself. */ return CURLE_BAD_FUNCTION_ARGUMENT; } } @@ -1587,8 +1590,6 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) (void) size; /* Always 1. */ - /* TODO: this loop is broken. If `nitems` is <= 4, some encoders will - * return STOP_FILLING without adding any data and this loops infinitely. */ do { hasread = FALSE; ret = readback_part(part, buffer, nitems, &hasread); @@ -1604,7 +1605,7 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) } /* Rewind mime stream. */ -static CURLcode mime_rewind(curl_mimepart *part) +CURLcode Curl_mime_rewind(curl_mimepart *part) { return mime_part_rewind(part) == CURL_SEEKFUNC_OK? CURLE_OK: CURLE_SEND_FAIL_REWIND; @@ -1636,7 +1637,7 @@ static curl_off_t multipart_size(curl_mime *mime) size = boundarysize; /* Final boundary - CRLF after headers. */ for(part = mime->firstpart; part; part = part->nextpart) { - curl_off_t sz = mime_size(part); + curl_off_t sz = Curl_mime_size(part); if(sz < 0) size = sz; @@ -1649,7 +1650,7 @@ static curl_off_t multipart_size(curl_mime *mime) } /* Get/compute mime size. */ -static curl_off_t mime_size(curl_mimepart *part) +curl_off_t Curl_mime_size(curl_mimepart *part) { curl_off_t size; @@ -1664,8 +1665,7 @@ static curl_off_t mime_size(curl_mimepart *part) if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) { /* Compute total part size. */ size += slist_size(part->curlheaders, 2, NULL, 0); - size += slist_size(part->userheaders, 2, - STRCONST("Content-Type")); + size += slist_size(part->userheaders, 2, STRCONST("Content-Type")); size += 2; /* CRLF after headers. */ } return size; @@ -1680,7 +1680,7 @@ CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...) va_list ap; va_start(ap, fmt); - s = vaprintf(fmt, ap); + s = curl_mvaprintf(fmt, ap); va_end(ap); if(s) { @@ -1773,7 +1773,7 @@ CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, curl_slist_free_all(part->curlheaders); part->curlheaders = NULL; - /* Be sure we will not access old headers later. */ + /* Be sure we won't access old headers later. */ if(part->state.state == MIMESTATE_CURLHEADERS) mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL); @@ -1899,7 +1899,7 @@ CURLcode Curl_mime_prepare_headers(struct Curl_easy *data, } /* Recursively reset paused status in the given part. */ -static void mime_unpause(curl_mimepart *part) +void Curl_mime_unpause(curl_mimepart *part) { if(part) { if(part->lastreadstatus == CURL_READFUNC_PAUSE) @@ -1911,264 +1911,12 @@ static void mime_unpause(curl_mimepart *part) curl_mimepart *subpart; for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) - mime_unpause(subpart); + Curl_mime_unpause(subpart); } } } } -struct cr_mime_ctx { - struct Curl_creader super; - curl_mimepart *part; - curl_off_t total_len; - curl_off_t read_len; - CURLcode error_result; - BIT(seen_eos); - BIT(errored); -}; - -static CURLcode cr_mime_init(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - ctx->total_len = -1; - ctx->read_len = 0; - return CURLE_OK; -} - -/* Real client reader to installed client callbacks. */ -static CURLcode cr_mime_read(struct Curl_easy *data, - struct Curl_creader *reader, - char *buf, size_t blen, - size_t *pnread, bool *peos) -{ - struct cr_mime_ctx *ctx = reader->ctx; - size_t nread; - - - /* Once we have errored, we will return the same error forever */ - if(ctx->errored) { - CURL_TRC_READ(data, "cr_mime_read(len=%zu) is errored -> %d, eos=0", - blen, ctx->error_result); - *pnread = 0; - *peos = FALSE; - return ctx->error_result; - } - if(ctx->seen_eos) { - CURL_TRC_READ(data, "cr_mime_read(len=%zu) seen eos -> 0, eos=1", blen); - *pnread = 0; - *peos = TRUE; - return CURLE_OK; - } - /* respect length limitations */ - if(ctx->total_len >= 0) { - curl_off_t remain = ctx->total_len - ctx->read_len; - if(remain <= 0) - blen = 0; - else if(remain < (curl_off_t)blen) - blen = (size_t)remain; - } - - if(blen <= 4) { - /* TODO: Curl_mime_read() may go into an infinite loop when reading - * such small lengths. Returning 0 bytes read is a fix that only works - * as request upload buffers will get flushed eventually and larger - * reads will happen again. */ - CURL_TRC_READ(data, "cr_mime_read(len=%zu), too small, return", blen); - *pnread = 0; - *peos = FALSE; - goto out; - } - - nread = Curl_mime_read(buf, 1, blen, ctx->part); - CURL_TRC_READ(data, "cr_mime_read(len=%zu), mime_read() -> %zd", - blen, nread); - - switch(nread) { - case 0: - if((ctx->total_len >= 0) && (ctx->read_len < ctx->total_len)) { - failf(data, "client mime read EOF fail, " - "only %"FMT_OFF_T"/%"FMT_OFF_T - " of needed bytes read", ctx->read_len, ctx->total_len); - return CURLE_READ_ERROR; - } - *pnread = 0; - *peos = TRUE; - ctx->seen_eos = TRUE; - break; - - case CURL_READFUNC_ABORT: - failf(data, "operation aborted by callback"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_ABORTED_BY_CALLBACK; - return CURLE_ABORTED_BY_CALLBACK; - - case CURL_READFUNC_PAUSE: - /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ - CURL_TRC_READ(data, "cr_mime_read(len=%zu), paused by callback", blen); - data->req.keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ - *pnread = 0; - *peos = FALSE; - break; /* nothing was read */ - - case STOP_FILLING: - case READ_ERROR: - failf(data, "read error getting mime data"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_READ_ERROR; - return CURLE_READ_ERROR; - - default: - if(nread > blen) { - /* the read function returned a too large value */ - failf(data, "read function returned funny value"); - *pnread = 0; - *peos = FALSE; - ctx->errored = TRUE; - ctx->error_result = CURLE_READ_ERROR; - return CURLE_READ_ERROR; - } - ctx->read_len += nread; - if(ctx->total_len >= 0) - ctx->seen_eos = (ctx->read_len >= ctx->total_len); - *pnread = nread; - *peos = ctx->seen_eos; - break; - } - -out: - CURL_TRC_READ(data, "cr_mime_read(len=%zu, total=%" FMT_OFF_T - ", read=%"FMT_OFF_T") -> %d, %zu, %d", - blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos); - return CURLE_OK; -} - -static bool cr_mime_needs_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - return ctx->read_len > 0; -} - -static curl_off_t cr_mime_total_length(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - return ctx->total_len; -} - -static CURLcode cr_mime_resume_from(struct Curl_easy *data, - struct Curl_creader *reader, - curl_off_t offset) -{ - struct cr_mime_ctx *ctx = reader->ctx; - - if(offset > 0) { - curl_off_t passed = 0; - - do { - char scratch[4*1024]; - size_t readthisamountnow = - (offset - passed > (curl_off_t)sizeof(scratch)) ? - sizeof(scratch) : - curlx_sotouz(offset - passed); - size_t nread; - - nread = Curl_mime_read(scratch, 1, readthisamountnow, ctx->part); - passed += (curl_off_t)nread; - if((nread == 0) || (nread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Could only read %" FMT_OFF_T - " bytes from the mime post", passed); - return CURLE_READ_ERROR; - } - } while(passed < offset); - - /* now, decrease the size of the read */ - if(ctx->total_len > 0) { - ctx->total_len -= offset; - - if(ctx->total_len <= 0) { - failf(data, "Mime post already completely uploaded"); - return CURLE_PARTIAL_FILE; - } - } - /* we have passed, proceed as normal */ - } - return CURLE_OK; -} - -static CURLcode cr_mime_rewind(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - CURLcode result = mime_rewind(ctx->part); - if(result) - failf(data, "Cannot rewind mime/post data"); - return result; -} - -static CURLcode cr_mime_unpause(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - mime_unpause(ctx->part); - return CURLE_OK; -} - -static bool cr_mime_is_paused(struct Curl_easy *data, - struct Curl_creader *reader) -{ - struct cr_mime_ctx *ctx = reader->ctx; - (void)data; - return (ctx->part && ctx->part->lastreadstatus == CURL_READFUNC_PAUSE); -} - -static const struct Curl_crtype cr_mime = { - "cr-mime", - cr_mime_init, - cr_mime_read, - Curl_creader_def_close, - cr_mime_needs_rewind, - cr_mime_total_length, - cr_mime_resume_from, - cr_mime_rewind, - cr_mime_unpause, - cr_mime_is_paused, - Curl_creader_def_done, - sizeof(struct cr_mime_ctx) -}; - -CURLcode Curl_creader_set_mime(struct Curl_easy *data, curl_mimepart *part) -{ - struct Curl_creader *r; - struct cr_mime_ctx *ctx; - CURLcode result; - - result = Curl_creader_create(&r, data, &cr_mime, CURL_CR_CLIENT); - if(result) - return result; - ctx = r->ctx; - ctx->part = part; - /* Make sure we will read the entire mime structure. */ - result = mime_rewind(ctx->part); - if(result) { - Curl_creader_free(data, r); - return result; - } - ctx->total_len = mime_size(ctx->part); - - return Curl_creader_set(data, r); -} #else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP) */ |