From f9ee2275cbc312c0b4cdbc338a4fbb76eb36fb9a Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 4 Feb 2021 13:49:00 +0000 Subject: [PATCH 06/11] gdatainputstream: Handle stop_chars_len internally as gsize Previously it was handled as a `gssize`, which meant that if the `stop_chars` string was longer than `G_MAXSSIZE` there would be an overflow. Signed-off-by: Philip Withnall Helps: #2319 --- gio/gdatainputstream.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c index 2e7750cb5..2cdcbda19 100644 --- a/gio/gdatainputstream.c +++ b/gio/gdatainputstream.c @@ -27,6 +27,7 @@ #include "gioenumtypes.h" #include "gioerror.h" #include "glibintl.h" +#include "gstrfuncsprivate.h" #include @@ -856,7 +857,7 @@ static gssize scan_for_chars (GDataInputStream *stream, gsize *checked_out, const char *stop_chars, - gssize stop_chars_len) + gsize stop_chars_len) { GBufferedInputStream *bstream; const char *buffer; @@ -952,7 +953,7 @@ typedef struct gsize checked; gchar *stop_chars; - gssize stop_chars_len; + gsize stop_chars_len; gsize length; } GDataInputStreamReadData; @@ -1078,12 +1079,17 @@ g_data_input_stream_read_async (GDataInputStream *stream, { GDataInputStreamReadData *data; GTask *task; + gsize stop_chars_len_unsigned; data = g_slice_new0 (GDataInputStreamReadData); - if (stop_chars_len == -1) - stop_chars_len = strlen (stop_chars); - data->stop_chars = g_memdup (stop_chars, stop_chars_len); - data->stop_chars_len = stop_chars_len; + + if (stop_chars_len < 0) + stop_chars_len_unsigned = strlen (stop_chars); + else + stop_chars_len_unsigned = (gsize) stop_chars_len; + + data->stop_chars = g_memdup2 (stop_chars, stop_chars_len_unsigned); + data->stop_chars_len = stop_chars_len_unsigned; data->last_saw_cr = FALSE; task = g_task_new (stream, cancellable, callback, user_data); @@ -1338,17 +1344,20 @@ g_data_input_stream_read_upto (GDataInputStream *stream, gssize found_pos; gssize res; char *data_until; + gsize stop_chars_len_unsigned; g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL); if (stop_chars_len < 0) - stop_chars_len = strlen (stop_chars); + stop_chars_len_unsigned = strlen (stop_chars); + else + stop_chars_len_unsigned = (gsize) stop_chars_len; bstream = G_BUFFERED_INPUT_STREAM (stream); checked = 0; - while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1) + while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len_unsigned)) == -1) { if (g_buffered_input_stream_get_available (bstream) == g_buffered_input_stream_get_buffer_size (bstream)) -- 2.30.1