Use wtap_read_bytes() to skip over bytes when reading a record.

Allow file_read() to take a null pointer as a buffer argument; a null
argument means "do everything except copy the bytes from the file to the
user buffer".  That means that wtap_read_bytes() and
wtap_read_bytes_or_eof() also support a null pointer as a buffer
argument.

Use wtap_read_bytes() with a null buffer argument rather than
file_skip() to skip forward over data.

This fixes some places where files were mis-identified as ERF files, as
the ERF open heuristics now get a short "read" error if they try to skip
over more bytes than exist in the file.

Change-Id: I4f73499d877c1f582e2bcf9b045034880cb09622
Reviewed-on: https://code.wireshark.org/review/17974
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2016-09-28 16:45:23 -07:00
parent a3ce2336b2
commit 48a66835ee
17 changed files with 73 additions and 81 deletions

View File

@ -173,7 +173,7 @@ wtap_open_return_val capsa_open(wtap *wth, int *err, gchar **err_info)
/*
* Link speed, in megabytes/second?
*/
if (!file_skip(wth->fh, 2, err))
if (!wtap_read_bytes(wth->fh, NULL, 2, err, err_info))
return WTAP_OPEN_ERROR;
/*
@ -181,19 +181,19 @@ wtap_open_return_val capsa_open(wtap *wth, int *err, gchar **err_info)
* and two of which are zero? Two 2-byte numbers or flag fields,
* both of which are 1?
*/
if (!file_skip(wth->fh, 4, err))
if (!wtap_read_bytes(wth->fh, NULL, 4, err, err_info))
return WTAP_OPEN_ERROR;
/*
* File size, in bytes.
*/
if (!file_skip(wth->fh, 4, err))
if (!wtap_read_bytes(wth->fh, NULL, 4, err, err_info))
return WTAP_OPEN_ERROR;
/*
* Zeroes? Or upper 4 bytes of file size?
*/
if (!file_skip(wth->fh, 4, err))
if (!wtap_read_bytes(wth->fh, NULL, 4, err, err_info))
return WTAP_OPEN_ERROR;
/*
@ -251,7 +251,7 @@ static gboolean capsa_read(wtap *wth, int *err, gchar **err_info,
* first byte.
*/
capsa->base_offset = file_tell(wth->fh);
if (!file_skip(wth->fh, 1, err))
if (!wtap_read_bytes(wth->fh, NULL, 1, err, err_info))
return FALSE;
/*
@ -265,7 +265,7 @@ static gboolean capsa_read(wtap *wth, int *err, gchar **err_info,
* And finish processing all 805 bytes by skipping
* the last 4 bytes.
*/
if (!file_skip(wth->fh, 4, err))
if (!wtap_read_bytes(wth->fh, NULL, 4, err, err_info))
return FALSE;
}
@ -283,7 +283,7 @@ static gboolean capsa_read(wtap *wth, int *err, gchar **err_info,
* Skip over the padding, if any.
*/
if (padbytes != 0) {
if (!file_skip(wth->fh, padbytes, err))
if (!wtap_read_bytes(wth->fh, NULL, padbytes, err, err_info))
return FALSE;
}
@ -339,8 +339,9 @@ capsa_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
* XXX - what is that? Measured statistics?
* Calculated statistics?
*/
if (!file_skip(fh, (capsarec_hdr.count1 + capsarec_hdr.count2)*4,
err))
if (!wtap_read_bytes(fh, NULL,
(capsarec_hdr.count1 + capsarec_hdr.count2)*4,
err, err_info))
return -1;
header_size += (capsarec_hdr.count1 + capsarec_hdr.count2)*4;
break;

View File

@ -231,8 +231,6 @@ extern wtap_open_return_val erf_open(wtap *wth, int *err, gchar **err_info)
guint16 rlen;
guint64 erf_ext_header;
guint8 type;
gboolean r;
gchar * buffer;
memset(&prevts, 0, sizeof(prevts));
@ -290,8 +288,16 @@ extern wtap_open_return_val erf_open(wtap *wth, int *err, gchar **err_info)
/* Skip PAD records, timestamps may not be set */
if ((header.type & 0x7F) == ERF_TYPE_PAD) {
if (file_seek(wth->fh, packet_size, SEEK_CUR, err) == -1) {
return WTAP_OPEN_ERROR;
if (!wtap_read_bytes(wth->fh, NULL, packet_size, err, err_info)) {
if (*err != WTAP_ERR_SHORT_READ) {
/* A real error */
return WTAP_OPEN_ERROR;
}
/* ERF record too short, accept the file,
only if the very first records have been successfully checked */
if (i < MIN_RECORDS_FOR_ERF_CHECK) {
return WTAP_OPEN_NOT_MINE;
}
}
continue;
}
@ -367,8 +373,6 @@ extern wtap_open_return_val erf_open(wtap *wth, int *err, gchar **err_info)
break;
}
/* The file_seek function do not return an error if the end of file
is reached whereas the record is truncated */
if (packet_size > WTAP_MAX_PACKET_SIZE) {
/*
* Probably a corrupt capture file or a file that's not an ERF file
@ -376,11 +380,7 @@ extern wtap_open_return_val erf_open(wtap *wth, int *err, gchar **err_info)
*/
return WTAP_OPEN_NOT_MINE;
}
buffer=(gchar *)g_malloc(packet_size);
r = wtap_read_bytes(wth->fh, buffer, packet_size, err, err_info);
g_free(buffer);
if (!r) {
if (!wtap_read_bytes(wth->fh, NULL, packet_size, err, err_info)) {
if (*err != WTAP_ERR_SHORT_READ) {
/* A real error */
return WTAP_OPEN_ERROR;

View File

@ -1145,21 +1145,6 @@ file_seek(FILE_T file, gint64 offset, int whence, int *err)
return file->pos + offset;
}
/*
* Skip forward the specified number of bytes in the file.
* Currently implemented as a wrapper around file_seek(),
* but if, for example, we ever add support for reading
* sequentially from a pipe, this could instead just skip
* forward by reading the bytes in question.
*/
gboolean
file_skip(FILE_T file, gint64 delta, int *err)
{
if (file_seek(file, delta, SEEK_CUR, err) == -1)
return FALSE;
return TRUE;
}
gint64
file_tell(FILE_T stream)
{
@ -1206,16 +1191,25 @@ file_read(void *buf, unsigned int len, FILE_T file)
return -1;
}
/* get len bytes to buf, or less than len if at the end */
/*
* Get len bytes to buf, or less than len if at the end;
* if buf is null, just throw the bytes away.
*/
got = 0;
do {
if (file->have) {
/* We have stuff in the output buffer; copy
what we have. */
n = file->have > len ? len : file->have;
memcpy(buf, file->next, n);
if (buf != NULL) {
memcpy(buf, file->next, n);
buf = (char *)buf + n;
}
file->next += n;
file->have -= n;
len -= n;
got += n;
file->pos += n;
} else if (file->err) {
/* We have nothing in the output buffer, and
we have an error that may not have been
@ -1236,13 +1230,7 @@ file_read(void *buf, unsigned int len, FILE_T file)
in the output buffer. */
if (fill_out_buffer(file) == -1)
return -1;
continue; /* no progress yet -- go back to memcpy() above */
}
/* update progress */
len -= n;
buf = (char *)buf + n;
got += n;
file->pos += n;
} while (len);
return (int)got;

View File

@ -30,7 +30,6 @@ extern FILE_T file_open(const char *path);
extern FILE_T file_fdopen(int fildes);
extern void file_set_random_access(FILE_T stream, gboolean random_flag, GPtrArray *seek);
WS_DLL_PUBLIC gint64 file_seek(FILE_T stream, gint64 offset, int whence, int *err);
extern gboolean file_skip(FILE_T file, gint64 delta, int *err);
WS_DLL_PUBLIC gint64 file_tell(FILE_T stream);
extern gint64 file_tell_raw(FILE_T stream);
extern int file_fstat(FILE_T stream, ws_statb64 *statb, int *err);

View File

@ -178,7 +178,7 @@ iptrace_read_rec_1_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
/*
* Skip the padding.
*/
if (!file_skip(fh, 3, err))
if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
return FALSE;
}
if (packet_size > WTAP_MAX_PACKET_SIZE) {
@ -371,7 +371,7 @@ iptrace_read_rec_2_0(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
/*
* Skip the padding.
*/
if (!file_skip(fh, 3, err))
if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
return FALSE;
}
if (packet_size > WTAP_MAX_PACKET_SIZE) {

View File

@ -462,7 +462,7 @@ static gint get_record(k12_t *file_data, FILE_T fh, gint64 file_offset,
* length? If the record length is always a multiple of
* 4 bytes, that won't happen.
*/
if ( ! file_skip( fh, K12_FILE_BLOB_LEN, err ) )
if ( ! wtap_read_bytes( fh, NULL, K12_FILE_BLOB_LEN, err, err_info ) )
return -1;
total_read += K12_FILE_BLOB_LEN;
}
@ -545,7 +545,7 @@ static gint get_record(k12_t *file_data, FILE_T fh, gint64 file_offset,
/*
* Skip the blob.
*/
if ( !file_skip( fh, K12_FILE_BLOB_LEN, err ) )
if ( !wtap_read_bytes( fh, NULL, K12_FILE_BLOB_LEN, err, err_info ) )
return -1;
total_read += K12_FILE_BLOB_LEN;

View File

@ -686,7 +686,7 @@ libpcap_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr,
/*
* Skip the padding.
*/
if (!file_skip(fh, 3, err))
if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
return FALSE;
}

View File

@ -101,7 +101,7 @@ mpeg_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
gint64 offset = file_tell(fh);
guint8 stream;
if (!file_skip(fh, 3, err))
if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
return FALSE;
if (!wtap_read_bytes(fh, &stream, sizeof stream, err, err_info))
@ -121,7 +121,8 @@ mpeg_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
switch (pack >> 62) {
case 1:
if (!file_skip(fh, 1, err))
if (!wtap_read_bytes(fh, NULL, 1, err,
err_info))
return FALSE;
if (!wtap_read_bytes(fh, &stuffing,
sizeof stuffing, err, err_info))

View File

@ -600,7 +600,7 @@ nettl_read_rec(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
bytes_to_read = 3;
if (bytes_to_read > datalen)
bytes_to_read = datalen;
if (!file_skip(fh, bytes_to_read, err))
if (!wtap_read_bytes(fh, NULL, bytes_to_read, err, err_info))
return FALSE;
datalen -= bytes_to_read;
if (datalen == 0) {

View File

@ -536,7 +536,7 @@ static gboolean ng_read_bytes(wtap *wth, void *buffer, unsigned int nbytes,
gboolean is_random, int *err, gchar **err_info);
static gboolean read_blob(FILE_T infile, ngsniffer_comp_stream_t *comp_stream,
int *err, gchar **err_info);
static gboolean ng_file_skip_seq(wtap *wth, gint64 delta, int *err,
static gboolean ng_skip_bytes_seq(wtap *wth, unsigned int count, int *err,
gchar **err_info);
static gboolean ng_file_seek_rand(wtap *wth, gint64 offset, int *err,
gchar **err_info);
@ -1056,7 +1056,7 @@ ngsniffer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
* Skip any extra data in the record.
*/
if (padding != 0) {
if (!ng_file_skip_seq(wth, padding, err,
if (!ng_skip_bytes_seq(wth, padding, err,
err_info))
return FALSE;
}
@ -1077,7 +1077,7 @@ ngsniffer_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
* and keep looping.
*/
if (padding != 0) {
if (!ng_file_skip_seq(wth, padding, err,
if (!ng_skip_bytes_seq(wth, padding, err,
err_info))
return FALSE;
}
@ -2588,7 +2588,7 @@ read_blob(FILE_T infile, ngsniffer_comp_stream_t *comp_stream, int *err,
/* Skip some number of bytes forward in the sequential stream. */
static gboolean
ng_file_skip_seq(wtap *wth, gint64 delta, int *err, gchar **err_info)
ng_skip_bytes_seq(wtap *wth, unsigned int count, int *err, gchar **err_info)
{
ngsniffer_t *ngsniffer;
char *buf;
@ -2597,26 +2597,24 @@ ng_file_skip_seq(wtap *wth, gint64 delta, int *err, gchar **err_info)
ngsniffer = (ngsniffer_t *)wth->priv;
if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_NGSNIFFER_UNCOMPRESSED) {
ngsniffer->seq.uncomp_offset += delta;
return file_skip(wth->fh, delta, err);
ngsniffer->seq.uncomp_offset += count;
return wtap_read_bytes(wth->fh, NULL, count, err, err_info);
}
g_assert(delta >= 0);
/* Ok, now read and discard "delta" bytes. */
/* Ok, now read and discard "count" bytes. */
buf = (char *)g_malloc(INBUF_SIZE);
while (delta != 0) {
if (delta > INBUF_SIZE)
while (count != 0) {
if (count > INBUF_SIZE)
amount_to_read = INBUF_SIZE;
else
amount_to_read = (unsigned int) delta;
amount_to_read = count;
if (!ng_read_bytes(wth, buf, amount_to_read, FALSE, err, err_info)) {
g_free(buf);
return FALSE; /* error */
}
delta -= amount_to_read;
count -= amount_to_read;
}
g_free(buf);

View File

@ -447,7 +447,7 @@ pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
/* jump over potential padding bytes at end of option */
if ( (oh->option_length % 4) != 0) {
if (!file_skip(fh, 4 - (oh->option_length % 4), err))
if (!wtap_read_bytes(fh, NULL, 4 - (oh->option_length % 4), err, err_info))
return -1;
block_read += 4 - (oh->option_length % 4);
}
@ -1227,7 +1227,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta
/* jump over potential padding bytes at end of the packet data */
if (padding != 0) {
if (!file_skip(fh, padding, err))
if (!wtap_read_bytes(fh, NULL, padding, err, err_info))
return FALSE;
block_read += padding;
}
@ -1518,7 +1518,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *
/* jump over potential padding bytes at end of the packet data */
if ((simple_packet.cap_len % 4) != 0) {
if (!file_skip(fh, 4 - (simple_packet.cap_len % 4), err))
if (!wtap_read_bytes(fh, NULL, 4 - (simple_packet.cap_len % 4), err, err_info))
return FALSE;
}
@ -1728,7 +1728,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
}
}
if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
ws_buffer_free(&nrb_rec);
return FALSE;
}
@ -1789,7 +1789,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
}
}
if (!file_skip(fh, PADDING4(nrb.record_len), err)) {
if (!wtap_read_bytes(fh, NULL, PADDING4(nrb.record_len), err, err_info)) {
ws_buffer_free(&nrb_rec);
return FALSE;
}
@ -1797,7 +1797,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
break;
default:
pcapng_debug("pcapng_read_name_resolution_block: unknown record type 0x%x", nrb.record_type);
if (!file_skip(fh, nrb.record_len + PADDING4(nrb.record_len), err)) {
if (!wtap_read_bytes(fh, NULL, nrb.record_len + PADDING4(nrb.record_len), err, err_info)) {
ws_buffer_free(&nrb_rec);
return FALSE;
}
@ -2281,7 +2281,7 @@ pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh,
#endif
{
/* No. Skip over this unknown block. */
if (!file_skip(fh, block_read, err)) {
if (!wtap_read_bytes(fh, NULL, block_read, err, err_info)) {
return FALSE;
}
}

View File

@ -365,14 +365,15 @@ static gboolean peekclassic_read_v7(wtap *wth, int *err, gchar **err_info,
/* Skip extra ignored data at the end of the packet. */
if ((guint32)sliceLength > wth->phdr.caplen) {
if (!file_skip(wth->fh, sliceLength - wth->phdr.caplen, err))
if (!wtap_read_bytes(wth->fh, NULL, sliceLength - wth->phdr.caplen,
err, err_info))
return FALSE;
}
/* Records are padded to an even length, so if the slice length
is odd, read the padding byte. */
if (sliceLength & 0x01) {
if (!file_skip(wth->fh, 1, err))
if (!wtap_read_bytes(wth->fh, NULL, 1, err, err_info))
return FALSE;
}

View File

@ -852,7 +852,7 @@ static gboolean peektagged_read(wtap *wth, int *err, gchar **err_info,
if (skip_len != 0) {
/* Skip extra junk at the end of the packet data. */
if (!file_skip(wth->fh, skip_len, err))
if (!wtap_read_bytes(wth->fh, NULL, skip_len, err, err_info))
return FALSE;
}

View File

@ -445,7 +445,7 @@ static gboolean snoop_read(wtap *wth, int *err, gchar **err_info,
* Skip over the padding, if any.
*/
if (padbytes != 0) {
if (!file_skip(wth->fh, padbytes, err))
if (!wtap_read_bytes(wth->fh, NULL, padbytes, err, err_info))
return FALSE;
}

View File

@ -720,7 +720,7 @@ static gboolean vwr_read_rec_header(FILE_T fh, int *rec_size, int *IS_TX, int *e
return FALSE;
}
else if (v_type != VT_FRAME) {
if (!file_skip(fh, f_len, err))
if (!wtap_read_bytes(fh, NULL, f_len, err, err_info))
return FALSE;
}
else {

View File

@ -256,7 +256,8 @@ extern gint wtap_num_file_types;
extern const char *compressed_file_extension_table[];
/*
* Read a given number of bytes from a file.
* Read a given number of bytes from a file into a buffer or, if
* buf is NULL, just discard them.
*
* If we succeed, return TRUE.
*
@ -276,7 +277,8 @@ wtap_read_bytes_or_eof(FILE_T fh, void *buf, unsigned int count, int *err,
gchar **err_info);
/*
* Read a given number of bytes from a file.
* Read a given number of bytes from a file into a buffer or, if
* buf is NULL, just discard them.
*
* If we succeed, return TRUE.
*

View File

@ -1268,7 +1268,8 @@ wtap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
}
/*
* Read a given number of bytes from a file.
* Read a given number of bytes from a file into a buffer or, if
* buf is NULL, just discard them.
*
* If we succeed, return TRUE.
*
@ -1299,7 +1300,8 @@ wtap_read_bytes_or_eof(FILE_T fh, void *buf, unsigned int count, int *err,
}
/*
* Read a given number of bytes from a file.
* Read a given number of bytes from a file into a buffer or, if
* buf is NULL, just discard them.
*
* If we succeed, return TRUE.
*