From a5d208adafec044b2c9e36ec5eb0f43db8be0564 Mon Sep 17 00:00:00 2001
From: Peter Bloomfield <PeterBloomfield@bellsouth.net>
Date: Fri, 29 Apr 2022 22:06:12 -0400
Subject: [PATCH 1/2] gtkimagedefinition: Check array bounds
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

`jhbuild build gtk+-3` with GCC 12 fails with:
```
In function ‘gtk_image_definition_ref’,
    inlined from ‘gtk_image_definition_new_empty’
    at ../../../../jhbuild/checkout/gtk+-3/gtk/gtkimagedefinition.c:107:10:
../../../../jhbuild/checkout/gtk+-3/gtk/gtkimagedefinition.c:241:13: error:
    array subscript ‘GtkImageDefinition {aka union _GtkImageDefinition}[0]’
    is partly outside array bounds of ‘GtkImageDefinitionEmpty[1]’
    {aka ‘struct _GtkImageDefinitionEmpty[1]’} [-Werror=array-bounds]
  241 |   def->empty.ref_count++;
      |   ~~~~~~~~~~^~~~~~~~~~
../../../../jhbuild/checkout/gtk+-3/gtk/gtkimagedefinition.c:
    In function ‘gtk_image_definition_new_empty’:
../../../../jhbuild/checkout/gtk+-3/gtk/gtkimagedefinition.c:105:34: note:
object ‘empty’ of size 8
  105 |   static GtkImageDefinitionEmpty empty = { GTK_IMAGE_EMPTY, 1 };
      |                                  ^~~~~
```
and many similar errors.

Fix it by casting `GtkImageDefinition` to `GtkImageDefinitionEmpty` or
similar, as appropriate.

Essentially backports 4dcd02e85315f487310e2e01fe9412706a77dc35 from main to gtk-3-24.
---
 gtk/gtkimagedefinition.c | 43 +++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/gtk/gtkimagedefinition.c b/gtk/gtkimagedefinition.c
index bd59420d5c..9ef8223911 100644
--- a/gtk/gtkimagedefinition.c
+++ b/gtk/gtkimagedefinition.c
@@ -121,12 +121,14 @@ gtk_image_definition_alloc (GtkImageType type)
     sizeof (GtkImageDefinitionSurface)
   };
   GtkImageDefinition *def;
+  GtkImageDefinitionEmpty *empty_def;
 
   g_assert (type < G_N_ELEMENTS (sizes));
 
   def = g_malloc0 (sizes[type]);
-  def->type = type;
-  def->empty.ref_count = 1;
+  empty_def = (GtkImageDefinitionEmpty *) def;
+  empty_def->type = type;
+  empty_def->ref_count = 1;
 
   return def;
 }
@@ -136,13 +138,15 @@ gtk_image_definition_new_pixbuf (GdkPixbuf *pixbuf,
                                  int        scale)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionPixbuf *pixbuf_def;
 
   if (pixbuf == NULL || scale <= 0)
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_PIXBUF);
-  def->pixbuf.pixbuf = g_object_ref (pixbuf);
-  def->pixbuf.scale = scale;
+  pixbuf_def = (GtkImageDefinitionPixbuf *) def;
+  pixbuf_def->pixbuf = g_object_ref (pixbuf);
+  pixbuf_def->scale = scale;
 
   return def;
 }
@@ -151,12 +155,14 @@ GtkImageDefinition *
 gtk_image_definition_new_stock (const char *stock_id)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionStock *stock_def;
 
   if (stock_id == NULL || stock_id[0] == '\0')
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_STOCK);
-  def->stock.id = g_strdup (stock_id);
+  stock_def = (GtkImageDefinitionStock *) def;
+  stock_def->id = g_strdup (stock_id);
 
   return def;
 }
@@ -165,13 +171,15 @@ GtkImageDefinition *
 gtk_image_definition_new_icon_set (GtkIconSet *icon_set)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionIconSet *icon_set_def;
 
   if (icon_set == NULL)
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_ICON_SET);
+  icon_set_def = (GtkImageDefinitionIconSet *) def;
 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-  def->icon_set.icon_set = gtk_icon_set_ref (icon_set);
+  icon_set_def->icon_set = gtk_icon_set_ref (icon_set);
 G_GNUC_END_IGNORE_DEPRECATIONS;
 
   return def;
@@ -182,13 +190,15 @@ gtk_image_definition_new_animation (GdkPixbufAnimation *animation,
                                     int                 scale)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionAnimation *animation_def;
 
   if (animation == NULL || scale <= 0)
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_ANIMATION);
-  def->animation.animation = g_object_ref (animation);
-  def->animation.scale = scale;
+  animation_def = (GtkImageDefinitionAnimation *) def;
+  animation_def->animation = g_object_ref (animation);
+  animation_def->scale = scale;
 
   return def;
 }
@@ -197,12 +207,14 @@ GtkImageDefinition *
 gtk_image_definition_new_icon_name (const char *icon_name)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionIconName *icon_name_def;
 
   if (icon_name == NULL || icon_name[0] == '\0')
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_ICON_NAME);
-  def->icon_name.icon_name = g_strdup (icon_name);
+  icon_name_def = (GtkImageDefinitionIconName *) def;
+  icon_name_def->icon_name = g_strdup (icon_name);
 
   return def;
 }
@@ -211,12 +223,14 @@ GtkImageDefinition *
 gtk_image_definition_new_gicon (GIcon *gicon)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionGIcon *gicon_def;
 
   if (gicon == NULL)
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_GICON);
-  def->gicon.gicon = g_object_ref (gicon);
+  gicon_def = (GtkImageDefinitionGIcon *) def;
+  gicon_def->gicon = g_object_ref (gicon);
 
   return def;
 }
@@ -225,12 +239,14 @@ GtkImageDefinition *
 gtk_image_definition_new_surface (cairo_surface_t *surface)
 {
   GtkImageDefinition *def;
+  GtkImageDefinitionSurface *surface_def;
 
   if (surface == NULL)
     return NULL;
 
   def = gtk_image_definition_alloc (GTK_IMAGE_SURFACE);
-  def->surface.surface = cairo_surface_reference (surface);
+  surface_def = (GtkImageDefinitionSurface *) def;
+  surface_def->surface = cairo_surface_reference (surface);
 
   return def;
 }
@@ -238,7 +254,10 @@ gtk_image_definition_new_surface (cairo_surface_t *surface)
 GtkImageDefinition *
 gtk_image_definition_ref (GtkImageDefinition *def)
 {
-  def->empty.ref_count++;
+  GtkImageDefinitionEmpty *empty_def;
+
+  empty_def = (GtkImageDefinitionEmpty *) def;
+  empty_def->ref_count++;
 
   return def;
 }
-- 
2.38.0

