aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/lib/mime.c
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-10-11 21:07:18 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-10-11 21:17:24 +0300
commit1df197e6035ea9826bfedee7d48812e318ba9c7a (patch)
tree76b8e9de41820755adf209854d06a84a8b5a1988 /contrib/libs/curl/lib/mime.c
parentf9c007ea1b59b960201def74990810b26ecdfd48 (diff)
downloadydb-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.c364
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) */