From 592880a3caf0b6f48b1dda6fbcf6a734237fcd43 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 24 Jan 2021 15:27:00 +0100 Subject: tests/server/getpart.c: properly deal with binary data containing NUL bytes --- tests/server/getpart.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/tests/server/getpart.c b/tests/server/getpart.c index 32b55bc61..68158530b 100644 --- a/tests/server/getpart.c +++ b/tests/server/getpart.c @@ -95,6 +95,33 @@ CURLcode Curl_convert_clone(struct Curl_easy *data, 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() * @@ -113,7 +140,8 @@ CURLcode Curl_convert_clone(struct Curl_easy *data, * 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; char *newptr; @@ -126,17 +154,16 @@ static int readline(char **buffer, size_t *bufsize, FILE *stream) } for(;;) { - size_t length; int bytestoread = curlx_uztosi(*bufsize - offset); if(!fgets(*buffer + offset, bytestoread, stream)) return (offset != 0) ? GPE_OK : GPE_END_OF_FILE; - length = offset + strlen(*buffer + offset); - if(*(*buffer + length - 1) == '\n') + *length = offset + line_length(*buffer + offset, bytestoread); + if(*(*buffer + *length - 1) == '\n') break; - offset = length; - if(length < *bufsize - 1) + offset = *length; + if(*length < *bufsize - 1) continue; 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_alloc, /* dest buffer allocated size */ char *src_buf, /* source buffer */ + size_t src_len, /* source buffer length */ int src_b64) /* != 0 if source is base64 encoded */ { size_t need_alloc = 0; - size_t src_len = strlen(src_buf); if(!src_len) return GPE_OK; @@ -293,6 +320,7 @@ int getpart(char **outbuf, size_t *outlen, } len; size_t bufsize = 0; size_t outalloc = 256; + size_t datalen; int in_wanted_part = 0; int base64 = 0; int error; @@ -313,7 +341,7 @@ int getpart(char **outbuf, size_t *outlen, 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; EAT_SPACE(ptr); @@ -321,7 +349,8 @@ int getpart(char **outbuf, size_t *outlen, if('<' != *ptr) { if(in_wanted_part) { show(("=> %s", buffer)); - error = appenddata(outbuf, outlen, &outalloc, buffer, base64); + error = appenddata(outbuf, outlen, &outalloc, buffer, datalen, + base64); if(error) break; } @@ -459,7 +488,7 @@ int getpart(char **outbuf, size_t *outlen, if(in_wanted_part) { show(("=> %s", buffer)); - error = appenddata(outbuf, outlen, &outalloc, buffer, base64); + error = appenddata(outbuf, outlen, &outalloc, buffer, datalen, base64); if(error) break; } -- cgit v1.2.1