forked from osmocom/wireshark
wiretap: fix truncated reads while reading compressed file formats
A lot of file dissectors (pcapng, json, etc.) assumed that the packet size is equal to the file size. This is not true if the file was compressed and could result in silently truncating reads or failing to open a file (if the compressed file is larger than the actual data). Observe that a lot of file dissectors are simply copies of each other. Move the fixed implementation to wtap.c and reuse the methods everywhere else. While at it, avoid an unnecessary large allocation/read in ruby_marshal. Change-Id: I8e9cd0af9c4d1bd37789a3b509146ae2182a5379 Reviewed-on: https://code.wireshark.org/review/30570 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Dario Lombardo <lomato@gmail.com> Tested-by: Dario Lombardo <lomato@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
parent
a0bb983834
commit
961f1388e4
|
@ -15,6 +15,7 @@ import os.path
|
|||
import subprocesstest
|
||||
import sys
|
||||
import unittest
|
||||
import fixtures
|
||||
|
||||
# XXX Currently unused. It would be nice to be able to use this below.
|
||||
time_output_args = ('-Tfields', '-e', 'frame.number', '-e', 'frame.time_epoch', '-e', 'frame.time_delta')
|
||||
|
@ -110,3 +111,16 @@ class case_fileformat_pcapng(subprocesstest.SubprocessTestCase):
|
|||
)
|
||||
self.assertTrue(self.diffOutput(capture_proc.stdout_str, baseline_str, 'tshark', baseline_file))
|
||||
|
||||
|
||||
@fixtures.mark_usefixtures('test_env')
|
||||
@fixtures.uses_fixtures
|
||||
class case_fileformat_mime(subprocesstest.SubprocessTestCase):
|
||||
def test_mime_pcapng_gz(self, cmd_tshark, dirs):
|
||||
'''Test that the full uncompressed contents is shown.'''
|
||||
capture_file = os.path.join(dirs.capture_dir, 'icmp.pcapng.gz')
|
||||
proc = self.runProcess((cmd_tshark,
|
||||
'-r', capture_file,
|
||||
'-Xread_format:MIME Files Format',
|
||||
'-Tfields', '-e', 'frame.len', '-e', 'pcapng.block.length',
|
||||
))
|
||||
self.assertEqual(proc.stdout_str.strip(), '480\t128,128,88,88,132,132,132,132')
|
||||
|
|
|
@ -22,71 +22,6 @@
|
|||
#define BER_UNI_TAG_SEQ 16 /* SEQUENCE, SEQUENCE OF */
|
||||
#define BER_UNI_TAG_SET 17 /* SET, SET OF */
|
||||
|
||||
static gboolean ber_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
gint64 file_size;
|
||||
int packet_size;
|
||||
|
||||
if ((file_size = wtap_file_size(wth, err)) == -1)
|
||||
return FALSE;
|
||||
|
||||
if (file_size > G_MAXINT) {
|
||||
/*
|
||||
* Probably a corrupt capture file; don't blow up trying
|
||||
* to allocate space for an immensely-large packet.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("ber: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
|
||||
file_size, G_MAXINT);
|
||||
return FALSE;
|
||||
}
|
||||
packet_size = (int)file_size;
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
|
||||
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
rec->ts.secs = 0;
|
||||
rec->ts.nsecs = 0;
|
||||
|
||||
return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean ber_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
*err = 0;
|
||||
|
||||
offset = file_tell(wth->fh);
|
||||
|
||||
/* there is only ever one packet */
|
||||
if (offset != 0)
|
||||
return FALSE;
|
||||
|
||||
*data_offset = offset;
|
||||
|
||||
return ber_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean ber_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
/* there is only one packet */
|
||||
if(seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return ber_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
wtap_open_return_val ber_open(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
#define BER_BYTES_TO_CHECK 8
|
||||
|
@ -159,8 +94,8 @@ wtap_open_return_val ber_open(wtap *wth, int *err, gchar **err_info)
|
|||
wth->file_encap = WTAP_ENCAP_BER;
|
||||
wth->snapshot_length = 0;
|
||||
|
||||
wth->subtype_read = ber_read;
|
||||
wth->subtype_seek_read = ber_seek_read;
|
||||
wth->subtype_read = wtap_full_file_read;
|
||||
wth->subtype_seek_read = wtap_full_file_seek_read;
|
||||
wth->file_tsprec = WTAP_TSPREC_SEC;
|
||||
|
||||
return WTAP_OPEN_MINE;
|
||||
|
|
|
@ -15,76 +15,16 @@
|
|||
#include "json.h"
|
||||
#include <wsutil/wsjson.h>
|
||||
|
||||
static gboolean json_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
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("json: 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;
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
|
||||
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
rec->ts.secs = 0;
|
||||
rec->ts.nsecs = 0;
|
||||
|
||||
return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean json_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
/* there is only one packet */
|
||||
if (seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return json_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean json_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
*err = 0;
|
||||
|
||||
offset = file_tell(wth->fh);
|
||||
|
||||
/* there is only ever one packet */
|
||||
if (offset != 0)
|
||||
return FALSE;
|
||||
|
||||
*data_offset = offset;
|
||||
|
||||
return json_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
/* Maximum size of json file. */
|
||||
#define MAX_FILE_SIZE (50*1024*1024)
|
||||
|
||||
wtap_open_return_val json_open(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
guint8* filebuf;
|
||||
int bytes_read;
|
||||
|
||||
/* XXX checking the full file contents might be a bit expensive, maybe
|
||||
* resort to simpler heuristics like '{' or '[' (with some other chars)? */
|
||||
filebuf = (guint8*)g_malloc0(MAX_FILE_SIZE);
|
||||
if (!filebuf)
|
||||
return WTAP_OPEN_ERROR;
|
||||
|
@ -115,8 +55,8 @@ wtap_open_return_val json_open(wtap *wth, int *err, gchar **err_info)
|
|||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_JSON;
|
||||
wth->file_encap = WTAP_ENCAP_JSON;
|
||||
wth->file_tsprec = WTAP_TSPREC_SEC;
|
||||
wth->subtype_read = json_read;
|
||||
wth->subtype_seek_read = json_seek_read;
|
||||
wth->subtype_read = wtap_full_file_read;
|
||||
wth->subtype_seek_read = wtap_full_file_seek_read;
|
||||
wth->snapshot_length = 0;
|
||||
|
||||
g_free(filebuf);
|
||||
|
|
|
@ -13,18 +13,6 @@
|
|||
|
||||
#include "wtap.h"
|
||||
|
||||
/*
|
||||
* 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 50MB.
|
||||
*/
|
||||
#define MAX_FILE_SIZE (50*1024*1024)
|
||||
|
||||
wtap_open_return_val json_open(wtap *wth, int *err, gchar **err_info);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,83 +81,6 @@ static const mime_files_t magic_files[] = {
|
|||
|
||||
#define N_MAGIC_TYPES (sizeof(magic_files) / sizeof(magic_files[0]))
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define MAX_FILE_SIZE G_MAXINT
|
||||
|
||||
static gboolean
|
||||
mime_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
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;
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
|
||||
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
rec->ts.secs = 0;
|
||||
rec->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)
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
*err = 0;
|
||||
|
||||
offset = file_tell(wth->fh);
|
||||
|
||||
/* there is only ever one packet */
|
||||
if (offset != 0)
|
||||
return FALSE;
|
||||
|
||||
*data_offset = offset;
|
||||
|
||||
return mime_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mime_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
/* there is only one packet */
|
||||
if (seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return mime_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
wtap_open_return_val
|
||||
mime_file_open(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
|
@ -206,8 +129,8 @@ mime_file_open(wtap *wth, int *err, gchar **err_info)
|
|||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_MIME;
|
||||
wth->file_encap = WTAP_ENCAP_MIME;
|
||||
wth->file_tsprec = WTAP_TSPREC_SEC;
|
||||
wth->subtype_read = mime_read;
|
||||
wth->subtype_seek_read = mime_seek_read;
|
||||
wth->subtype_read = wtap_full_file_read;
|
||||
wth->subtype_seek_read = wtap_full_file_seek_read;
|
||||
wth->snapshot_length = 0;
|
||||
|
||||
return WTAP_OPEN_MINE;
|
||||
|
|
|
@ -18,39 +18,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
static gboolean rfc7468_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
gint64 file_size;
|
||||
int packet_size;
|
||||
|
||||
if ((file_size = wtap_file_size(wth, err)) == -1)
|
||||
return FALSE;
|
||||
|
||||
if (file_size > G_MAXINT) {
|
||||
/*
|
||||
* Probably a corrupt capture file; don't blow up trying
|
||||
* to allocate space for an immensely-large packet.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("rfc7468: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
|
||||
file_size, G_MAXINT);
|
||||
return FALSE;
|
||||
}
|
||||
packet_size = (int)file_size;
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
|
||||
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
rec->ts.secs = 0;
|
||||
rec->ts.nsecs = 0;
|
||||
|
||||
return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
|
||||
}
|
||||
|
||||
/* 128 bytes should be enough to contain any line. Strictly speaking, 64 is
|
||||
enough, but we provide some leeway to accomodate nonconformant producers and
|
||||
trailing whitespace. The 2 extra bytes are for the trailing newline and NUL
|
||||
|
@ -79,38 +46,6 @@ static char *read_complete_text_line(char line[MAX_LINE_LENGTH], FILE_T fh, int
|
|||
return line_end;
|
||||
}
|
||||
|
||||
static gboolean rfc7468_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
*err = 0;
|
||||
|
||||
offset = file_tell(wth->fh);
|
||||
|
||||
/* there is only ever one packet */
|
||||
if (offset != 0)
|
||||
return FALSE;
|
||||
|
||||
*data_offset = offset;
|
||||
|
||||
return rfc7468_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean rfc7468_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
/* there is only one packet */
|
||||
if (seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return rfc7468_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
//
|
||||
// Arbitrary value - we don't want to read all of a huge non-RFC 7468 file
|
||||
// only to find no pre-encapsulation boundary.
|
||||
|
@ -154,8 +89,8 @@ wtap_open_return_val rfc7468_open(wtap *wth, int *err, gchar **err_info)
|
|||
wth->snapshot_length = 0;
|
||||
wth->file_tsprec = WTAP_TSPREC_SEC;
|
||||
|
||||
wth->subtype_read = rfc7468_read;
|
||||
wth->subtype_seek_read = rfc7468_seek_read;
|
||||
wth->subtype_read = wtap_full_file_read;
|
||||
wth->subtype_seek_read = wtap_full_file_seek_read;
|
||||
|
||||
return WTAP_OPEN_MINE;
|
||||
}
|
||||
|
|
|
@ -16,83 +16,6 @@
|
|||
|
||||
#include "ruby_marshal.h"
|
||||
|
||||
/*
|
||||
* 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 50MB.
|
||||
*/
|
||||
#define MAX_FILE_SIZE (50*1024*1024)
|
||||
|
||||
static gboolean ruby_marshal_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
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("ruby_marshal: 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;
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0;
|
||||
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
rec->ts.secs = 0;
|
||||
rec->ts.nsecs = 0;
|
||||
|
||||
return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean ruby_marshal_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf,
|
||||
int *err, gchar **err_info)
|
||||
{
|
||||
/* there is only one packet */
|
||||
if (seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return ruby_marshal_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean ruby_marshal_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
*err = 0;
|
||||
|
||||
offset = file_tell(wth->fh);
|
||||
|
||||
/* there is only ever one packet */
|
||||
if (offset != 0)
|
||||
return FALSE;
|
||||
|
||||
*data_offset = offset;
|
||||
|
||||
return ruby_marshal_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean is_ruby_marshal(const guint8* filebuf)
|
||||
{
|
||||
if (filebuf[0] != RUBY_MARSHAL_MAJOR)
|
||||
|
@ -128,44 +51,32 @@ static gboolean is_ruby_marshal(const guint8* filebuf)
|
|||
|
||||
wtap_open_return_val ruby_marshal_open(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
guint8* filebuf;
|
||||
/* The size of this buffer should match the expectations of is_ruby_marshal */
|
||||
guint8 filebuf[3];
|
||||
int bytes_read;
|
||||
|
||||
filebuf = (guint8*)g_malloc0(MAX_FILE_SIZE);
|
||||
if (!filebuf)
|
||||
return WTAP_OPEN_ERROR;
|
||||
|
||||
bytes_read = file_read(filebuf, MAX_FILE_SIZE, wth->fh);
|
||||
bytes_read = file_read(filebuf, sizeof(filebuf), wth->fh);
|
||||
if (bytes_read < 0) {
|
||||
/* Read error. */
|
||||
*err = file_error(wth->fh, err_info);
|
||||
g_free(filebuf);
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
if (bytes_read == 0) {
|
||||
/* empty file, not *anybody's* */
|
||||
g_free(filebuf);
|
||||
return WTAP_OPEN_NOT_MINE;
|
||||
}
|
||||
|
||||
if (!is_ruby_marshal(filebuf)) {
|
||||
g_free(filebuf);
|
||||
if (bytes_read != sizeof(filebuf) || !is_ruby_marshal(filebuf)) {
|
||||
return WTAP_OPEN_NOT_MINE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) {
|
||||
g_free(filebuf);
|
||||
return WTAP_OPEN_ERROR;
|
||||
}
|
||||
|
||||
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_RUBY_MARSHAL;
|
||||
wth->file_encap = WTAP_ENCAP_RUBY_MARSHAL;
|
||||
wth->file_tsprec = WTAP_TSPREC_SEC;
|
||||
wth->subtype_read = ruby_marshal_read;
|
||||
wth->subtype_seek_read = ruby_marshal_seek_read;
|
||||
wth->subtype_read = wtap_full_file_read;
|
||||
wth->subtype_seek_read = wtap_full_file_seek_read;
|
||||
wth->snapshot_length = 0;
|
||||
|
||||
g_free(filebuf);
|
||||
return WTAP_OPEN_MINE;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,72 +14,6 @@
|
|||
#include <wsutil/buffer.h>
|
||||
#include "tnef.h"
|
||||
|
||||
static gboolean tnef_read_file(wtap *wth, FILE_T fh, wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
gint64 file_size;
|
||||
int packet_size;
|
||||
|
||||
if ((file_size = wtap_file_size(wth, err)) == -1)
|
||||
return FALSE;
|
||||
|
||||
if (file_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
|
||||
/*
|
||||
* Probably a corrupt capture file; don't blow up trying
|
||||
* to allocate space for an immensely-large packet.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("tnef: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
|
||||
file_size, WTAP_MAX_PACKET_SIZE_STANDARD);
|
||||
return FALSE;
|
||||
}
|
||||
packet_size = (int)file_size;
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
|
||||
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
rec->ts.secs = 0;
|
||||
rec->ts.nsecs = 0;
|
||||
|
||||
return wtap_read_packet_bytes(fh, buf, packet_size, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean tnef_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
||||
{
|
||||
gint64 offset;
|
||||
|
||||
*err = 0;
|
||||
|
||||
offset = file_tell(wth->fh);
|
||||
|
||||
/* there is only ever one packet */
|
||||
if (offset)
|
||||
return FALSE;
|
||||
|
||||
*data_offset = offset;
|
||||
|
||||
return tnef_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
|
||||
static gboolean tnef_seek_read(wtap *wth, gint64 seek_off,
|
||||
wtap_rec *rec,
|
||||
Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
/* there is only one packet */
|
||||
if(seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return tnef_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
wtap_open_return_val tnef_open(wtap *wth, int *err, gchar **err_info)
|
||||
{
|
||||
guint32 magic;
|
||||
|
@ -99,8 +33,8 @@ wtap_open_return_val tnef_open(wtap *wth, int *err, gchar **err_info)
|
|||
wth->file_encap = WTAP_ENCAP_TNEF;
|
||||
wth->snapshot_length = 0;
|
||||
|
||||
wth->subtype_read = tnef_read;
|
||||
wth->subtype_seek_read = tnef_seek_read;
|
||||
wth->subtype_read = wtap_full_file_read;
|
||||
wth->subtype_seek_read = wtap_full_file_seek_read;
|
||||
wth->file_tsprec = WTAP_TSPREC_SEC;
|
||||
|
||||
return WTAP_OPEN_MINE;
|
||||
|
|
|
@ -309,6 +309,19 @@ gboolean
|
|||
wtap_read_packet_bytes(FILE_T fh, Buffer *buf, guint length, int *err,
|
||||
gchar **err_info);
|
||||
|
||||
/*
|
||||
* Implementation of wth->subtype_read that reads the full file contents
|
||||
* as a single packet.
|
||||
*/
|
||||
gboolean
|
||||
wtap_full_file_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset);
|
||||
|
||||
/*
|
||||
* Implementation of wth->subtype_seek_read that reads the full file contents
|
||||
* as a single packet.
|
||||
*/
|
||||
gboolean
|
||||
wtap_full_file_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info);
|
||||
#endif /* __WTAP_INT_H__ */
|
||||
|
||||
/*
|
||||
|
|
|
@ -1450,6 +1450,95 @@ wtap_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wtap_full_file_read_file(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
gint64 file_size;
|
||||
int packet_size = 0;
|
||||
const int block_size = 1024 * 1024;
|
||||
|
||||
if ((file_size = wtap_file_size(wth, err)) == -1)
|
||||
return FALSE;
|
||||
|
||||
if (file_size > G_MAXINT) {
|
||||
/*
|
||||
* Avoid allocating space for an immensely-large file.
|
||||
*/
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("%s: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
|
||||
wtap_encap_short_string(wth->file_encap), file_size, G_MAXINT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compressed files might expand to a larger size than the actual file
|
||||
* size. Try to read the full size and then read in smaller increments
|
||||
* to avoid frequent memory reallocations.
|
||||
*/
|
||||
int buffer_size = block_size * (1 + (int)file_size / block_size);
|
||||
for (;;) {
|
||||
if (buffer_size <= 0) {
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
*err_info = g_strdup_printf("%s: Uncompressed file is bigger than maximum of %u",
|
||||
wtap_encap_short_string(wth->file_encap), G_MAXINT);
|
||||
return FALSE;
|
||||
}
|
||||
ws_buffer_assure_space(buf, buffer_size);
|
||||
int nread = file_read(ws_buffer_start_ptr(buf) + packet_size, buffer_size - packet_size, fh);
|
||||
if (nread < 0) {
|
||||
*err = file_error(fh, err_info);
|
||||
if (*err == 0)
|
||||
*err = WTAP_ERR_BAD_FILE;
|
||||
return FALSE;
|
||||
}
|
||||
packet_size += nread;
|
||||
if (packet_size != buffer_size) {
|
||||
/* EOF */
|
||||
break;
|
||||
}
|
||||
buffer_size += block_size;
|
||||
}
|
||||
|
||||
rec->rec_type = REC_TYPE_PACKET;
|
||||
rec->presence_flags = 0; /* yes, we have no bananas^Wtime stamp */
|
||||
rec->ts.secs = 0;
|
||||
rec->ts.nsecs = 0;
|
||||
rec->rec_header.packet_header.caplen = packet_size;
|
||||
rec->rec_header.packet_header.len = packet_size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
wtap_full_file_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
||||
{
|
||||
gint64 offset = file_tell(wth->fh);
|
||||
|
||||
/* There is only one packet with the full file contents. */
|
||||
if (offset != 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*data_offset = offset;
|
||||
return wtap_full_file_read_file(wth, wth->fh, &wth->rec, wth->rec_data, err, err_info);
|
||||
}
|
||||
|
||||
gboolean
|
||||
wtap_full_file_seek_read(wtap *wth, gint64 seek_off, wtap_rec *rec, Buffer *buf, int *err, gchar **err_info)
|
||||
{
|
||||
/* There is only one packet with the full file contents. */
|
||||
if (seek_off > 0) {
|
||||
*err = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
|
||||
return FALSE;
|
||||
|
||||
return wtap_full_file_read_file(wth, wth->random_fh, rec, buf, err, err_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the library.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue