aboutsummaryrefslogtreecommitdiffstats
path: root/file.c
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2020-10-26 16:00:40 -0700
committerGuy Harris <gharris@sonic.net>2020-10-26 16:52:58 -0700
commit639891651f7caca3a427467edbe608f90e88a060 (patch)
tree090aca21de57ed68ae54b538fffc2742e998ed9d /file.c
parenta88d72dc8e91312a1fe95ef54d7a1dc0a1350a7d (diff)
Impose limits on the number of records we read.
Start the limit at 2^32-1, as we use a guint32 to store the frame number. With Qt prior to Qt 6, lower the limit to 53 million packets; this should fix issue #16908.
Diffstat (limited to 'file.c')
-rw-r--r--file.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/file.c b/file.c
index b43a44183a..7ad30ec37f 100644
--- a/file.c
+++ b/file.c
@@ -117,6 +117,23 @@ static void ref_time_packets(capture_file *cf);
#define PROGBAR_SHOW_DELAY 0.5
/*
+ * Maximum number of records we support in a file.
+ *
+ * It is, at most, the maximum value of a guint32, as we use a guint32
+ * for the frame number.
+ *
+ * We allow it to be set to a lower value; see issue #16908 for why
+ * we're doing this. Thanks, Qt!
+ */
+static guint32 max_records = G_MAXUINT32;
+
+void
+cf_set_max_records(guint max_records_arg)
+{
+ max_records = max_records_arg;
+}
+
+/*
* We could probably use g_signal_...() instead of the callbacks below but that
* would require linking our CLI programs to libgobject and creating an object
* instance for the signals.
@@ -482,6 +499,7 @@ cf_read(capture_file *cf, gboolean reloading)
{
int err = 0;
gchar *err_info = NULL;
+ volatile gboolean too_many_records = FALSE;
gchar *name_ptr;
progdlg_t *volatile progbar = NULL;
GTimer *prog_timer = g_timer_new();
@@ -569,7 +587,7 @@ cf_read(capture_file *cf, gboolean reloading)
ws_buffer_init(&buf, 1514);
TRY {
- int count = 0;
+ guint32 count = 0;
gint64 file_pos;
gint64 data_offset;
@@ -580,6 +598,14 @@ cf_read(capture_file *cf, gboolean reloading)
while ((wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info,
&data_offset))) {
if (size >= 0) {
+ if (cf->count == max_records) {
+ /*
+ * Quit if we've already read the maximum number of
+ * records allowed.
+ */
+ too_many_records = TRUE;
+ break;
+ }
count++;
file_pos = wtap_read_so_far(cf->provider.wth);
@@ -732,6 +758,18 @@ cf_read(capture_file *cf, gboolean reloading)
if any. */
cfile_read_failure_alert_box(NULL, err, err_info);
return CF_READ_ERROR;
+ } else if (too_many_records) {
+ simple_message_box(ESD_TYPE_WARN, NULL,
+ "The remaining packets in the file were discarded.\n"
+ "\n"
+ "As a lot of packets from the original file will be missing,\n"
+ "remember to be careful when saving the current content to a file.\n"
+ "\n"
+ "The command-line utility editcap can be used to split "
+ "the file into multiple smaller files",
+ "The file contains more records than the maximum "
+ "supported number of records, %u.", max_records);
+ return CF_READ_ERROR;
} else
return CF_READ_OK;
}