Source code

Revision control

Copy as Markdown

Other Tools

diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -1489,36 +1489,46 @@ cairo_cff_font_subset_dict_strings (cair
status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
if (unlikely (status))
return status;
}
return CAIRO_STATUS_SUCCESS;
}
-static unsigned char *
-type2_decode_integer (unsigned char *p, int *integer)
+static cairo_status_t
+type2_decode_integer (unsigned char **pp, unsigned char *end, int *integer)
{
+ unsigned char *p = *pp;
if (*p == 28) {
+ if (p + 3 > end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
*integer = p[1] << 8 | p[2];
- p += 3;
+ *pp += 3;
} else if (*p <= 246) {
- *integer = *p++ - 139;
+ *integer = *p - 139;
+ *pp += 1;
} else if (*p <= 250) {
+ if (p + 2 > end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
*integer = (p[0] - 247) * 256 + p[1] + 108;
- p += 2;
+ *pp += 2;
} else if (*p <= 254) {
+ if (p + 2 > end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
*integer = -(p[0] - 251) * 256 - p[1] - 108;
- p += 2;
+ *pp += 2;
} else { /* *p == 255 */
- /* 16.16 fixed-point number. The fraction is ignored. */
- *integer = (int16_t)((p[1] << 8) | p[2]);
- p += 5;
+ if (p + 5 > end)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ /* 16.16 fixed-point number. The fraction is ignored. */
+ *integer = (int16_t)((p[1] << 8) | p[2]);
+ *pp += 5;
}
- return p;
+ return CAIRO_STATUS_SUCCESS;
}
/* Type 2 charstring parser for finding calls to local or global
* subroutines. For non Opentype CFF fonts it also gets the glyph
* widths.
*
* When we find a subroutine operator, the subroutine is marked as in
* use and recursively followed. The subroutine number is the value on
@@ -1548,21 +1558,24 @@ cairo_cff_parse_charstring (cairo_cff_fo
{
unsigned char *p = charstring;
unsigned char *end = charstring + length;
int integer;
int hint_bytes;
int sub_num;
cff_index_element_t *element;
int fd;
+ cairo_status_t status;
while (p < end) {
if (*p == 28 || *p >= 32) {
/* Integer value */
- p = type2_decode_integer (p, &integer);
+ status = type2_decode_integer (&p, end, &integer);
+ if (unlikely (status))
+ return status;
font->type2_stack_size++;
font->type2_stack_top_value = integer;
font->type2_stack_top_is_int = TRUE;
if (!font->type2_seen_first_int) {
font->type2_width = integer;
font->type2_seen_first_int = TRUE;
}
} else if (*p == TYPE2_hstem || *p == TYPE2_vstem ||