mirror of
https://github.com/curl/curl.git
synced 2025-02-17 14:59:45 +08:00
parent
b0d18dbcc0
commit
0bd50335fe
55
lib/mime.c
55
lib/mime.c
@ -314,7 +314,7 @@ static char *escape_string(struct Curl_easy *data,
|
||||
|
||||
Curl_dyn_init(&db, CURL_MAX_INPUT_LENGTH);
|
||||
|
||||
for(result = Curl_dyn_add(&db, ""); !result && *src; src++) {
|
||||
for(result = Curl_dyn_addn(&db, STRCONST("")); !result && *src; src++) {
|
||||
for(p = table; *p && **p != *src; p++)
|
||||
;
|
||||
|
||||
@ -339,9 +339,9 @@ static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len)
|
||||
}
|
||||
|
||||
/* Get a header from an slist. */
|
||||
static char *search_header(struct curl_slist *hdrlist, const char *hdr)
|
||||
static char *search_header(struct curl_slist *hdrlist,
|
||||
const char *hdr, size_t len)
|
||||
{
|
||||
size_t len = strlen(hdr);
|
||||
char *value = NULL;
|
||||
|
||||
for(; !value && hdrlist; hdrlist = hdrlist->next)
|
||||
@ -758,7 +758,7 @@ static void mime_file_free(void *ptr)
|
||||
static size_t readback_bytes(struct mime_state *state,
|
||||
char *buffer, size_t bufsize,
|
||||
const char *bytes, size_t numbytes,
|
||||
const char *trail)
|
||||
const char *trail, size_t traillen)
|
||||
{
|
||||
size_t sz;
|
||||
size_t offset = curlx_sotouz(state->offset);
|
||||
@ -768,13 +768,11 @@ static size_t readback_bytes(struct mime_state *state,
|
||||
bytes += offset;
|
||||
}
|
||||
else {
|
||||
size_t tsz = strlen(trail);
|
||||
|
||||
sz = offset - numbytes;
|
||||
if(sz >= tsz)
|
||||
if(sz >= traillen)
|
||||
return 0;
|
||||
bytes = trail + sz;
|
||||
sz = tsz - sz;
|
||||
sz = traillen - sz;
|
||||
}
|
||||
|
||||
if(sz > bufsize)
|
||||
@ -943,13 +941,14 @@ static size_t readback_part(curl_mimepart *part,
|
||||
mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders);
|
||||
else {
|
||||
sz = readback_bytes(&part->state, buffer, bufsize,
|
||||
hdr->data, strlen(hdr->data), "\r\n");
|
||||
hdr->data, strlen(hdr->data), STRCONST("\r\n"));
|
||||
if(!sz)
|
||||
mimesetstate(&part->state, part->state.state, hdr->next);
|
||||
}
|
||||
break;
|
||||
case MIMESTATE_EOH:
|
||||
sz = readback_bytes(&part->state, buffer, bufsize, "\r\n", 2, "");
|
||||
sz = readback_bytes(&part->state, buffer, bufsize, STRCONST("\r\n"),
|
||||
STRCONST(""));
|
||||
if(!sz)
|
||||
mimesetstate(&part->state, MIMESTATE_BODY, NULL);
|
||||
break;
|
||||
@ -1014,13 +1013,18 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
|
||||
mime->state.offset += 2;
|
||||
break;
|
||||
case MIMESTATE_BOUNDARY1:
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, "\r\n--", 4, "");
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, STRCONST("\r\n--"),
|
||||
STRCONST(""));
|
||||
if(!sz)
|
||||
mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part);
|
||||
break;
|
||||
case MIMESTATE_BOUNDARY2:
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
|
||||
strlen(mime->boundary), part? "\r\n": "--\r\n");
|
||||
if(part)
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
|
||||
MIME_BOUNDARY_LEN, STRCONST("\r\n"));
|
||||
else
|
||||
sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
|
||||
MIME_BOUNDARY_LEN, STRCONST("--\r\n"));
|
||||
if(!sz) {
|
||||
mimesetstate(&mime->state, MIMESTATE_CONTENT, part);
|
||||
}
|
||||
@ -1614,10 +1618,9 @@ CURLcode Curl_mime_rewind(curl_mimepart *part)
|
||||
|
||||
/* Compute header list size. */
|
||||
static size_t slist_size(struct curl_slist *s,
|
||||
size_t overhead, const char *skip)
|
||||
size_t overhead, const char *skip, size_t skiplen)
|
||||
{
|
||||
size_t size = 0;
|
||||
size_t skiplen = skip? strlen(skip): 0;
|
||||
|
||||
for(; s; s = s->next)
|
||||
if(!skip || !match_header(s, skip, skiplen))
|
||||
@ -1635,7 +1638,7 @@ static curl_off_t multipart_size(curl_mime *mime)
|
||||
if(!mime)
|
||||
return 0; /* Not present -> empty. */
|
||||
|
||||
boundarysize = 4 + strlen(mime->boundary) + 2;
|
||||
boundarysize = 4 + MIME_BOUNDARY_LEN + 2;
|
||||
size = boundarysize; /* Final boundary - CRLF after headers. */
|
||||
|
||||
for(part = mime->firstpart; part; part = part->nextpart) {
|
||||
@ -1666,8 +1669,8 @@ curl_off_t Curl_mime_size(curl_mimepart *part)
|
||||
|
||||
if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) {
|
||||
/* Compute total part size. */
|
||||
size += slist_size(part->curlheaders, 2, NULL);
|
||||
size += slist_size(part->userheaders, 2, "Content-Type");
|
||||
size += slist_size(part->curlheaders, 2, NULL, 0);
|
||||
size += slist_size(part->userheaders, 2, STRCONST("Content-Type"));
|
||||
size += 2; /* CRLF after headers. */
|
||||
}
|
||||
return size;
|
||||
@ -1743,10 +1746,9 @@ const char *Curl_mime_contenttype(const char *filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool content_type_match(const char *contenttype, const char *target)
|
||||
static bool content_type_match(const char *contenttype,
|
||||
const char *target, size_t len)
|
||||
{
|
||||
size_t len = strlen(target);
|
||||
|
||||
if(contenttype && strncasecompare(contenttype, target, len))
|
||||
switch(contenttype[len]) {
|
||||
case '\0':
|
||||
@ -1782,7 +1784,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
/* Check if content type is specified. */
|
||||
customct = part->mimetype;
|
||||
if(!customct)
|
||||
customct = search_header(part->userheaders, "Content-Type");
|
||||
customct = search_header(part->userheaders, STRCONST("Content-Type"));
|
||||
if(customct)
|
||||
contenttype = customct;
|
||||
|
||||
@ -1811,12 +1813,12 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
boundary = mime->boundary;
|
||||
}
|
||||
else if(contenttype && !customct &&
|
||||
content_type_match(contenttype, "text/plain"))
|
||||
content_type_match(contenttype, STRCONST("text/plain")))
|
||||
if(strategy == MIMESTRATEGY_MAIL || !part->filename)
|
||||
contenttype = NULL;
|
||||
|
||||
/* Issue content-disposition header only if not already set by caller. */
|
||||
if(!search_header(part->userheaders, "Content-Disposition")) {
|
||||
if(!search_header(part->userheaders, STRCONST("Content-Disposition"))) {
|
||||
if(!disposition)
|
||||
if(part->filename || part->name ||
|
||||
(contenttype && !strncasecompare(contenttype, "multipart/", 10)))
|
||||
@ -1863,7 +1865,8 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
}
|
||||
|
||||
/* Content-Transfer-Encoding header. */
|
||||
if(!search_header(part->userheaders, "Content-Transfer-Encoding")) {
|
||||
if(!search_header(part->userheaders,
|
||||
STRCONST("Content-Transfer-Encoding"))) {
|
||||
if(part->encoder)
|
||||
cte = part->encoder->name;
|
||||
else if(contenttype && strategy == MIMESTRATEGY_MAIL &&
|
||||
@ -1887,7 +1890,7 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
|
||||
curl_mimepart *subpart;
|
||||
|
||||
disposition = NULL;
|
||||
if(content_type_match(contenttype, "multipart/form-data"))
|
||||
if(content_type_match(contenttype, STRCONST("multipart/form-data")))
|
||||
disposition = "form-data";
|
||||
for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
|
||||
ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -91,8 +91,8 @@ struct mime_state {
|
||||
curl_off_t offset; /* State-dependent offset. */
|
||||
};
|
||||
|
||||
/* minimum buffer size for the boundary string */
|
||||
#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS + 1)
|
||||
/* Boundary string length. */
|
||||
#define MIME_BOUNDARY_LEN (24 + MIME_RAND_BOUNDARY_CHARS)
|
||||
|
||||
/* A mime multipart. */
|
||||
struct curl_mime {
|
||||
@ -100,7 +100,7 @@ struct curl_mime {
|
||||
curl_mimepart *parent; /* Parent part. */
|
||||
curl_mimepart *firstpart; /* First part. */
|
||||
curl_mimepart *lastpart; /* Last part. */
|
||||
char boundary[MIME_BOUNDARY_LEN]; /* The part boundary. */
|
||||
char boundary[MIME_BOUNDARY_LEN + 1]; /* The part boundary. */
|
||||
struct mime_state state; /* Current readback state. */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user