Update ydk-pixbuf, backport upstream changes to io-xpm #9642

Bastien Nocera <hadess@hadess.net>
  io-xpm: Fix "format not a string literal" errors
  xpm: Sanity check XPM file dimensions
  xpm: Simplify error path
  xpm: Fail when XPM file doesn't contain enough data

Philip Withnall <withnall@endlessm.com>
  io-xpm: Handle fseek() failure

Federico Mena Quintero <federico@gnome.org>
  Use gdk_pixbuf_get_pixels(); don't access the pixels field directly

Tobias Stoeckmann <tobias@stoeckmann.org>
  XPM: Fix undefined behaviour (signed integer overflow)
This commit is contained in:
Robin Gareus 2024-02-23 01:19:28 +01:00
parent 64e42a465b
commit 0fa8c5add4
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -178,7 +178,6 @@ parse_color (const char *spec,
XPMColor *colorPtr)
{
if (spec[0] == '#') {
char fmt[16];
int i, red, green, blue;
if ((i = strlen (spec + 1)) % 3) {
@ -186,25 +185,27 @@ parse_color (const char *spec,
}
i /= 3;
g_snprintf (fmt, 16, "%%%dx%%%dx%%%dx", i, i, i);
if (sscanf (spec + 1, fmt, &red, &green, &blue) != 3) {
return FALSE;
}
if (i == 4) {
if (sscanf (spec + 1, "%4x%4x%4x", &red, &green, &blue) != 3)
return FALSE;
colorPtr->red = red;
colorPtr->green = green;
colorPtr->blue = blue;
} else if (i == 1) {
if (sscanf (spec + 1, "%1x%1x%1x", &red, &green, &blue) != 3)
return FALSE;
colorPtr->red = (red * 65535) / 15;
colorPtr->green = (green * 65535) / 15;
colorPtr->blue = (blue * 65535) / 15;
} else if (i == 2)
{
} else if (i == 2) {
if (sscanf (spec + 1, "%2x%2x%2x", &red, &green, &blue) != 3)
return FALSE;
colorPtr->red = (red * 65535) / 255;
colorPtr->green = (green * 65535) / 255;
colorPtr->blue = (blue * 65535) / 255;
} else /* if (i == 3) */ {
if (sscanf (spec + 1, "%3x%3x%3x", &red, &green, &blue) != 3)
return FALSE;
colorPtr->red = (red * 65535) / 4095;
colorPtr->green = (green * 65535) / 4095;
colorPtr->blue = (blue * 65535) / 4095;
@ -400,7 +401,8 @@ file_buffer (enum buf_op op, gpointer handle)
case op_cmap:
xpm_seek_char (h->infile, '"');
fseek (h->infile, -1, SEEK_CUR);
if (fseek (h->infile, -1, SEEK_CUR) != 0)
return NULL;
/* Fall through to the xpm_read_string. */
case op_body:
@ -455,7 +457,8 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl
GHashTable *color_hash;
XPMColor *colors, *color, *fallbackcolor;
guchar *pixtmp;
GdkPixbuf *pixbuf;
GdkPixbuf *pixbuf = NULL;
gint rowstride;
fallbackcolor = NULL;
@ -493,7 +496,16 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl
return NULL;
}
if (cpp <= 0 || cpp >= 32) {
/* Check from libXpm's ParsePixels() */
if ((h > 0 && w >= UINT_MAX / h) ||
w * h >= UINT_MAX / sizeof(unsigned int)) {
g_set_error_literal (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Invalid XPM header"));
return NULL;
}
if (cpp <= 0 || cpp >= 32 || w >= G_MAXINT / cpp) {
g_set_error_literal (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
@ -542,10 +554,7 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Cannot read XPM colormap"));
g_hash_table_destroy (color_hash);
g_free (name_buf);
g_free (colors);
return NULL;
goto out;
}
color = &colors[cnt];
@ -580,20 +589,25 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
_("Cannot allocate memory for loading XPM image"));
g_hash_table_destroy (color_hash);
g_free (colors);
g_free (name_buf);
return NULL;
goto out;
}
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
wbytes = w * cpp;
for (ycnt = 0; ycnt < h; ycnt++) {
pixtmp = pixbuf->pixels + ycnt * pixbuf->rowstride;
pixtmp = gdk_pixbuf_get_pixels (pixbuf) + ycnt * rowstride;
buffer = (*get_buf) (op_body, handle);
if ((!buffer) || (strlen (buffer) < wbytes))
continue;
if ((!buffer) || (strlen (buffer) < wbytes)) {
/* Advertised width doesn't match pixels */
g_set_error_literal (error,
GDK_PIXBUF_ERROR,
GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
_("Dimensions do not match data"));
goto out;
}
for (n = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) {
strncpy (pixel_str, &buffer[n], cpp);
@ -630,6 +644,14 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl
}
return pixbuf;
out:
g_hash_table_destroy (color_hash);
g_free (colors);
g_free (name_buf);
g_clear_object (&pixbuf);
return NULL;
}
/* Shared library entry point for file loading */
@ -742,7 +764,11 @@ gdk_pixbuf__xpm_image_stop_load (gpointer data,
NULL,
context->user_data);
if (context->update_func)
(* context->update_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data);
(* context->update_func) (pixbuf,
0, 0,
gdk_pixbuf_get_width (pixbuf),
gdk_pixbuf_get_height (pixbuf),
context->user_data);
g_object_unref (pixbuf);
retval = TRUE;