From d734fe4562dae74d0ae9a9db1b4bc2ee6f31783a Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 31 Dec 2013 23:48:02 +0000 Subject: When reading MIME-encapsulated files, read the entire file at once, don't break it into chunks. This means we don't need to do reassembly in the MIME-encapsulated-data dissector. svn path=/trunk/; revision=54525 --- wiretap/mime_file.c | 100 ++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 46 deletions(-) (limited to 'wiretap/mime_file.c') diff --git a/wiretap/mime_file.c b/wiretap/mime_file.c index a9703c3909..1925d174df 100644 --- a/wiretap/mime_file.c +++ b/wiretap/mime_file.c @@ -49,11 +49,6 @@ #include "buffer.h" #include "mime_file.h" -typedef struct { - gboolean last_packet; - -} mime_file_private_t; - typedef struct { const guint8 *magic; guint magic_len; @@ -89,67 +84,82 @@ static const mime_files_t magic_files[] = { #define N_MAGIC_TYPES (sizeof(magic_files) / sizeof(magic_files[0])) -static void -mime_set_pkthdr(struct wtap_pkthdr *phdr, int packet_size) +/* + * Impose a not-too-large limit on the maximum file size, to avoid eating + * up 99% of the (address space, swap partition, disk space for swap/page + * files); if we were to return smaller chunks and let the dissector do + * reassembly, it would *still* have to allocate a buffer the size of + * the file, so it's not as if we'd neve try to allocate a buffer the + * size of the file. + * + * For now, go for 16MB. + */ +#define MAX_FILE_SIZE (16*1024*1024) + +static gboolean +mime_read_file(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, + Buffer *buf, int *err, gchar **err_info) { - phdr->presence_flags = 0; + gint64 file_size; + int packet_size; + + if ((file_size = wtap_file_size(wth, err)) == -1) + return FALSE; + + if (file_size > MAX_FILE_SIZE) { + /* + * Don't blow up trying to allocate space for an + * immensely-large file. + */ + *err = WTAP_ERR_BAD_FILE; + *err_info = g_strdup_printf("mime_file: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u", + file_size, MAX_FILE_SIZE); + return FALSE; + } + packet_size = (int)file_size; + + phdr->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */ - phdr->ts.secs = 0; - phdr->ts.nsecs = 0; phdr->caplen = packet_size; phdr->len = packet_size; + + phdr->ts.secs = 0; + phdr->ts.nsecs = 0; + + return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info); } static gboolean mime_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { - mime_file_private_t *priv = (mime_file_private_t *) wth->priv; - - char _buf[WTAP_MAX_PACKET_SIZE]; - guint8 *buf; - int packet_size; - - if (priv->last_packet) { - *err = file_error(wth->fh, err_info); - return FALSE; - } - - *data_offset = file_tell(wth->fh); + gint64 offset; - /* try to read max WTAP_MAX_PACKET_SIZE bytes */ - packet_size = file_read(_buf, sizeof(_buf), wth->fh); + *err = 0; - if (packet_size <= 0) { - mime_set_pkthdr(&wth->phdr, 0); - priv->last_packet = TRUE; - /* signal error for packet-mime-encap */ - if (packet_size < 0) - wth->phdr.ts.nsecs = 1000000000; - return TRUE; - } + offset = file_tell(wth->fh); - mime_set_pkthdr(&wth->phdr, packet_size); + /* there is only ever one packet */ + if (offset != 0) + return FALSE; - /* copy to wth frame buffer */ - buffer_assure_space(wth->frame_buffer, packet_size); - buf = buffer_start_ptr(wth->frame_buffer); - memcpy(buf, _buf, packet_size); + *data_offset = offset; - return TRUE; + return mime_read_file(wth, wth->fh, &wth->phdr, wth->frame_buffer, err, err_info); } static gboolean -mime_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int length, int *err, gchar **err_info) +mime_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr, Buffer *buf, int length _U_, int *err, gchar **err_info) { - if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) { - *err_info = NULL; + /* there is only one packet */ + if (seek_off > 0) { + *err = 0; return FALSE; } - mime_set_pkthdr(phdr, length); + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; - return wtap_read_packet_bytes(wth->random_fh, buf, length, err, - err_info); + return mime_read_file(wth, wth->random_fh, phdr, buf, err, err_info); } int @@ -200,8 +210,6 @@ mime_file_open(wtap *wth, int *err, gchar **err_info) wth->subtype_seek_read = mime_seek_read; wth->snapshot_length = 0; - wth->priv = g_malloc0(sizeof(mime_file_private_t)); - return 1; } -- cgit v1.2.3