/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 - 2015
* License: GPL
- * Copyright (c) The Exim Maintainers 2015 - 2018
+ * Copyright (c) The Exim Maintainers 2015 - 2020
*/
#include "exim.h"
static ssize_t
mime_decode_asis(FILE* in, FILE* out, uschar* boundary)
{
- ssize_t len, size = 0;
- uschar buffer[MIME_MAX_LINE_LENGTH];
+ssize_t len, size = 0;
+uschar buffer[MIME_MAX_LINE_LENGTH];
- while(fgets(CS buffer, MIME_MAX_LINE_LENGTH, mime_stream) != NULL)
- {
- if (boundary != NULL
- && Ustrncmp(buffer, "--", 2) == 0
- && Ustrncmp((buffer+2), boundary, Ustrlen(boundary)) == 0
- )
- break;
+while(fgets(CS buffer, MIME_MAX_LINE_LENGTH, mime_stream) != NULL)
+ {
+ if (boundary != NULL
+ && Ustrncmp(buffer, "--", 2) == 0
+ && Ustrncmp((buffer+2), boundary, Ustrlen(boundary)) == 0
+ )
+ break;
- len = Ustrlen(buffer);
- if (fwrite(buffer, 1, (size_t)len, out) < len)
- return -1;
- size += len;
- } /* while */
- return size;
+ len = Ustrlen(buffer);
+ if (fwrite(buffer, 1, (size_t)len, out) < len)
+ return -1;
+ size += len;
+ } /* while */
+return size;
}
}
+/* reset all per-part mime variables */
static void
mime_vars_reset(void)
{
uschar * header = NULL;
struct mime_boundary_context nested_context;
-/* reserve a line buffer to work in */
-header = store_get(MIME_MAX_HEADER_SIZE+1);
+/* reserve a line buffer to work in. Assume tainted data. */
+header = store_get(MIME_MAX_HEADER_SIZE+1, TRUE);
/* Not actually used at the moment, but will be vital to fixing
* some RFC 2046 nonconformance later... */
if (rc != OK) break;
/* If we have a multipart entity and a boundary, go recursive */
- if ( (mime_content_type != NULL) &&
- (nested_context.boundary != NULL) &&
- (Ustrncmp(mime_content_type,"multipart",9) == 0) )
+ if ( mime_content_type && nested_context.boundary
+ && Ustrncmp(mime_content_type,"multipart",9) == 0)
{
DEBUG(D_acl)
debug_printf_indent("MIME: Entering multipart recursion, boundary '%s'\n",
rc = mime_acl_check(acl, f, &nested_context, user_msgptr, log_msgptr);
if (rc != OK) break;
}
- else if ( (mime_content_type != NULL) &&
- (Ustrncmp(mime_content_type,"message/rfc822",14) == 0) )
+ else if ( mime_content_type
+ && Ustrncmp(mime_content_type,"message/rfc822",14) == 0)
{
- const uschar *rfc822name = NULL;
- uschar filename[2048];
+ const uschar * rfc822name = NULL;
+ uschar * filename;
int file_nr = 0;
int result = 0;
/* must find first free sequential filename */
- do
+ for (gstring * g = string_get(64); result != -1; g->ptr = 0)
{
struct stat mystat;
- (void)string_format(filename, 2048,
+ g = string_fmt_append(g,
"%s/scan/%s/__rfc822_%05u", spool_directory, message_id, file_nr++);
/* security break */
if (file_nr >= 128)
goto NO_RFC822;
- result = stat(CS filename,&mystat);
- } while (result != -1);
+ result = stat(CS (filename = string_from_gstring(g)), &mystat);
+ }
rfc822name = filename;