gio: Prevent hang writing to a large GMemoryOutputStream

Fix a hang due to overflow by using unsigned numbers and explicitly
checking if the number overflows to zero.  This also fixes the previous
logic which assigned an int which may be negative to an unsigned number
resulting in sign extension and strange results.

Use gsize rather than int to allow for large streams on 64 bit machines.

https://bugzilla.gnome.org/show_bug.cgi?id=727988
This commit is contained in:
Ross Lagerwall 2014-10-29 22:05:32 +00:00
parent b3e3ed7386
commit 5a6f13d16f

View File

@ -594,12 +594,12 @@ array_resize (GMemoryOutputStream *ostream,
return TRUE;
}
static gint
g_nearest_pow (gint num)
static gsize
g_nearest_pow (gsize num)
{
gint n = 1;
gsize n = 1;
while (n < num)
while (n < num && n > 0)
n <<= 1;
return n;
@ -639,12 +639,10 @@ g_memory_output_stream_write (GOutputStream *stream,
* much memory.
*/
new_size = g_nearest_pow (priv->pos + count);
/* Check for overflow again. We have only checked if
pos + count > G_MAXSIZE, but it only catches the case of writing
more than 4GiB total on a 32-bit system. There's still the problem
of g_nearest_pow overflowing above 0x7fffffff, so we're
effectively limited to 2GiB. */
if (new_size < priv->len)
/* Check for overflow again. We have checked if
pos + count > G_MAXSIZE, but now check if g_nearest_pow () has
overflowed */
if (new_size == 0)
goto overflow;
new_size = MAX (new_size, MIN_ARRAY_SIZE);