Cherry-pick https://gitlab.freedesktop.org/cairo/cairo/-/commit/1569dcd4d8a2235052aa227dc9f5708cccaea23e draft
authorJonathan Kew <jkew@mozilla.com>
Mon, 19 Apr 2021 13:59:53 +0100
changeset 3667307 6cfc2b4cd55935f17cdb96aa307ea95fd7938287
parent 3667306 2aef1ea8afd40ad2d60641424d758dc69c86592f
child 3667308 919daaf50d14e1f5a204333f2bad8ac1e7c135fb
push id683063
push userjkew@mozilla.com
push dateMon, 19 Apr 2021 13:15:26 +0000
treeherdertry@919daaf50d14 [default view] [failures only]
milestone89.0a1
Cherry-pick https://gitlab.freedesktop.org/cairo/cairo/-/commit/1569dcd4d8a2235052aa227dc9f5708cccaea23e UBSan fixes in cairo-truetype-subset.c and cairo-array.c
gfx/cairo/cairo/src/cairo-array.c
gfx/cairo/cairo/src/cairo-truetype-subset.c
--- a/gfx/cairo/cairo/src/cairo-array.c
+++ b/gfx/cairo/cairo/src/cairo-array.c
@@ -500,16 +500,21 @@ cairo_status_t
 			     const cairo_user_data_array_t	*src)
 {
     /* discard any existing user-data */
     if (dst->num_elements != 0) {
 	_cairo_user_data_array_fini (dst);
 	_cairo_user_data_array_init (dst);
     }
 
+    /* don't call _cairo_array_append_multiple if there's nothing to do,
+     * as it assumes at least 1 element is to be appended */
+    if (src->num_elements == 0)
+        return CAIRO_STATUS_SUCCESS;
+
     return _cairo_array_append_multiple (dst,
 					 _cairo_array_index_const (src, 0),
 					 src->num_elements);
 }
 
 void
 _cairo_user_data_array_foreach (cairo_user_data_array_t     *array,
 				void (*func) (const void *key,
--- a/gfx/cairo/cairo/src/cairo-truetype-subset.c
+++ b/gfx/cairo/cairo/src/cairo-truetype-subset.c
@@ -1267,40 +1267,39 @@ static cairo_int_status_t
 _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
 			      unsigned long        table_offset,
 			      unsigned long        index,
 			      uint32_t            *ucs4)
 {
     cairo_status_t status;
     const cairo_scaled_font_backend_t *backend;
     tt_segment_map_t *map;
-    char buf[4];
+    tt_segment_map_t map_header;
     unsigned int num_segments, i;
     unsigned long size;
     uint16_t *start_code;
     uint16_t *end_code;
     uint16_t *delta;
     uint16_t *range_offset;
     uint16_t  c;
 
     backend = scaled_font->backend;
-    size = 4;
+    size = 4;  /* enough to read the two header fields we need */
     status = backend->load_truetype_table (scaled_font,
                                            TT_TAG_cmap, table_offset,
-					   (unsigned char *) &buf,
+					   (unsigned char *) &map_header,
 					   &size);
     if (unlikely (status))
 	return status;
 
     /* All table formats have the same first two words */
-    map = (tt_segment_map_t *) buf;
-    if (be16_to_cpu (map->format) != 4)
+    if (be16_to_cpu (map_header.format) != 4)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    size = be16_to_cpu (map->length);
+    size = be16_to_cpu (map_header.length);
     map = _cairo_malloc (size);
     if (unlikely (map == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = backend->load_truetype_table (scaled_font,
                                            TT_TAG_cmap, table_offset,
                                            (unsigned char *) map,
                                            &size);
@@ -1377,35 +1376,34 @@ fail:
 cairo_int_status_t
 _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
                                unsigned long        index,
                                uint32_t            *ucs4)
 {
     cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
     const cairo_scaled_font_backend_t *backend;
     tt_cmap_t *cmap;
-    char buf[4];
+    tt_cmap_t cmap_header;
     int num_tables, i;
     unsigned long size;
 
     backend = scaled_font->backend;
     if (!backend->load_truetype_table)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    size = 4;
+    size = 4;  /* only read the header fields 'version' and 'num_tables' */
     status = backend->load_truetype_table (scaled_font,
                                            TT_TAG_cmap, 0,
-					   (unsigned char *) &buf,
+					   (unsigned char *) &cmap_header,
 					   &size);
     if (unlikely (status))
 	return status;
 
-    cmap = (tt_cmap_t *) buf;
-    num_tables = be16_to_cpu (cmap->num_tables);
-    size = 4 + num_tables*sizeof(tt_cmap_index_t);
+    num_tables = be16_to_cpu (cmap_header.num_tables);
+    size = 4 + num_tables * sizeof (tt_cmap_index_t);
     cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
     if (unlikely (cmap == NULL))
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
     status = backend->load_truetype_table (scaled_font,
 	                                   TT_TAG_cmap, 0,
 					   (unsigned char *) cmap,
 					   &size);