summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-04-03 18:24:00 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-04-03 18:35:57 +0100
commita5e2a2ad2d03c217b9b27c537ee6a945bdc98a44 (patch)
tree4c521bb9f812aa840fc30f363de6790b1b537f1e
parent13cdfed894d48b30e28296c3a27c8361bf5506fb (diff)
[cairo-truetype-subset] Prevent accesses beyond the end of the glyph array.
Reject the font if we try to remap a composite glyph that exists outside the known set of glyphs.
-rw-r--r--src/cairo-truetype-subset.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 68c5ff3c..db3f95ba 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -85,8 +85,10 @@ struct _cairo_truetype_font {
};
-static int
-cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph);
+static cairo_status_t
+cairo_truetype_font_use_glyph (cairo_truetype_font_t *font,
+ unsigned short glyph,
+ unsigned short *out);
#define SFNT_VERSION 0x00010000
#define SFNT_STRING_MAX_LENGTH 65535
@@ -491,7 +493,7 @@ cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
return CAIRO_STATUS_SUCCESS;
}
-static void
+static cairo_status_t
cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
unsigned char *buffer)
{
@@ -501,19 +503,23 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
int has_more_components;
unsigned short flags;
unsigned short index;
+ cairo_status_t status;
if (font->status)
- return;
+ return font->status;
glyph_data = (tt_glyph_data_t *) buffer;
if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
- return;
+ return CAIRO_STATUS_SUCCESS;
composite_glyph = &glyph_data->glyph;
do {
flags = be16_to_cpu (composite_glyph->flags);
has_more_components = flags & TT_MORE_COMPONENTS;
- index = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index));
+ status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
+ if (status)
+ return status;
+
composite_glyph->index = cpu_to_be16 (index);
num_args = 1;
if (flags & TT_ARG_1_AND_2_ARE_WORDS)
@@ -526,6 +532,8 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
num_args += 3;
composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
} while (has_more_components);
+
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -607,7 +615,9 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
if (status)
goto FAIL;
- cairo_truetype_font_remap_composite_glyph (font, buffer);
+ status = cairo_truetype_font_remap_composite_glyph (font, buffer);
+ if (status)
+ goto FAIL;
}
}
@@ -938,16 +948,22 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font,
return _cairo_truetype_font_set_error (font, status);
}
-static int
-cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, int glyph)
+static cairo_status_t
+cairo_truetype_font_use_glyph (cairo_truetype_font_t *font,
+ unsigned short glyph,
+ unsigned short *out)
{
+ if (glyph >= font->num_glyphs_in_face)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
if (font->parent_to_subset[glyph] == 0) {
font->parent_to_subset[glyph] = font->base.num_glyphs;
font->glyphs[font->base.num_glyphs].parent_index = glyph;
font->base.num_glyphs++;
}
- return font->parent_to_subset[glyph];
+ *out = font->parent_to_subset[glyph];
+ return CAIRO_STATUS_SUCCESS;
}
static void
@@ -1043,7 +1059,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
cairo_status_t status;
const char *data = NULL; /* squelch bogus compiler warning */
unsigned long length = 0; /* squelch bogus compiler warning */
- unsigned long parent_glyph, offsets_length;
+ unsigned long offsets_length;
unsigned int i;
const unsigned long *string_offsets = NULL;
unsigned long num_strings = 0;
@@ -1053,8 +1069,9 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset,
return status;
for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
- parent_glyph = font->scaled_font_subset->glyphs[i];
- cairo_truetype_font_use_glyph (font, parent_glyph);
+ unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
+ status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
+ assert (status == CAIRO_STATUS_SUCCESS);
}
cairo_truetype_font_create_truetype_table_list (font);