tests/server/getpart.c: properly deal with binary data containing NUL bytes

This commit is contained in:
Fabian Keil 2021-01-24 15:27:00 +01:00 committed by Daniel Stenberg
parent 43eef423d6
commit 592880a3ca
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -95,6 +95,33 @@ CURLcode Curl_convert_clone(struct Curl_easy *data,
return CURLE_OK; return CURLE_OK;
} }
/*
* line_length()
*
* Counts the number of characters in a line including a new line.
* Unlike strlen() it does not stop at nul bytes.
*
*/
static size_t line_length(const char *buffer, int bytestocheck)
{
size_t length = 1;
while(*buffer != '\n' && --bytestocheck) {
length++;
buffer++;
}
if(*buffer != '\n') {
/*
* We didn't find a new line so the last byte must be a
* '\0' character inserted by fgets() which we should not
* count.
*/
length--;
}
return length;
}
/* /*
* readline() * readline()
* *
@ -113,7 +140,8 @@ CURLcode Curl_convert_clone(struct Curl_easy *data,
* GPE_OK * GPE_OK
*/ */
static int readline(char **buffer, size_t *bufsize, FILE *stream) static int readline(char **buffer, size_t *bufsize, size_t *length,
FILE *stream)
{ {
size_t offset = 0; size_t offset = 0;
char *newptr; char *newptr;
@ -126,17 +154,16 @@ static int readline(char **buffer, size_t *bufsize, FILE *stream)
} }
for(;;) { for(;;) {
size_t length;
int bytestoread = curlx_uztosi(*bufsize - offset); int bytestoread = curlx_uztosi(*bufsize - offset);
if(!fgets(*buffer + offset, bytestoread, stream)) if(!fgets(*buffer + offset, bytestoread, stream))
return (offset != 0) ? GPE_OK : GPE_END_OF_FILE; return (offset != 0) ? GPE_OK : GPE_END_OF_FILE;
length = offset + strlen(*buffer + offset); *length = offset + line_length(*buffer + offset, bytestoread);
if(*(*buffer + length - 1) == '\n') if(*(*buffer + *length - 1) == '\n')
break; break;
offset = length; offset = *length;
if(length < *bufsize - 1) if(*length < *bufsize - 1)
continue; continue;
newptr = realloc(*buffer, *bufsize * 2); newptr = realloc(*buffer, *bufsize * 2);
@ -179,10 +206,10 @@ static int appenddata(char **dst_buf, /* dest buffer */
size_t *dst_len, /* dest buffer data length */ size_t *dst_len, /* dest buffer data length */
size_t *dst_alloc, /* dest buffer allocated size */ size_t *dst_alloc, /* dest buffer allocated size */
char *src_buf, /* source buffer */ char *src_buf, /* source buffer */
size_t src_len, /* source buffer length */
int src_b64) /* != 0 if source is base64 encoded */ int src_b64) /* != 0 if source is base64 encoded */
{ {
size_t need_alloc = 0; size_t need_alloc = 0;
size_t src_len = strlen(src_buf);
if(!src_len) if(!src_len)
return GPE_OK; return GPE_OK;
@ -293,6 +320,7 @@ int getpart(char **outbuf, size_t *outlen,
} len; } len;
size_t bufsize = 0; size_t bufsize = 0;
size_t outalloc = 256; size_t outalloc = 256;
size_t datalen;
int in_wanted_part = 0; int in_wanted_part = 0;
int base64 = 0; int base64 = 0;
int error; int error;
@ -313,7 +341,7 @@ int getpart(char **outbuf, size_t *outlen,
couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0'; couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0';
while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) { while((error = readline(&buffer, &bufsize, &datalen, stream)) == GPE_OK) {
ptr = buffer; ptr = buffer;
EAT_SPACE(ptr); EAT_SPACE(ptr);
@ -321,7 +349,8 @@ int getpart(char **outbuf, size_t *outlen,
if('<' != *ptr) { if('<' != *ptr) {
if(in_wanted_part) { if(in_wanted_part) {
show(("=> %s", buffer)); show(("=> %s", buffer));
error = appenddata(outbuf, outlen, &outalloc, buffer, base64); error = appenddata(outbuf, outlen, &outalloc, buffer, datalen,
base64);
if(error) if(error)
break; break;
} }
@ -459,7 +488,7 @@ int getpart(char **outbuf, size_t *outlen,
if(in_wanted_part) { if(in_wanted_part) {
show(("=> %s", buffer)); show(("=> %s", buffer));
error = appenddata(outbuf, outlen, &outalloc, buffer, base64); error = appenddata(outbuf, outlen, &outalloc, buffer, datalen, base64);
if(error) if(error)
break; break;
} }