Source code

Revision control

Copy as Markdown

Other Tools

diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c
--- a/src/cairo-type1-subset.c
+++ b/src/cairo-type1-subset.c
@@ -1063,16 +1063,18 @@ cairo_type1_font_for_each_subr (cairo_ty
*
* or alternatively using -| and |- instead of RD and ND.
* The first number is the subroutine number.
*/
p = array_start;
while (p + 3 < cleartext_end && strncmp (p, "dup", 3) == 0) {
p = skip_token (p, cleartext_end);
+ if (p == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
/* get subr number */
subr_num = strtol (p, &end, 10);
if (p == end)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (subr_num < 0 || subr_num >= font->num_subrs)
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1080,32 +1082,41 @@ cairo_type1_font_for_each_subr (cairo_ty
/* get subr length */
p = end;
subr_length = strtol (p, &end, 10);
if (p == end)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* Skip past -| or RD to binary data. There is exactly one space
* between the -| or RD token and the encrypted data, thus '+ 1'. */
- subr_string = skip_token (end, cleartext_end) + 1;
+ subr_string = skip_token (end, cleartext_end);
+ if (subr_string == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ subr_string++;
+
+ /* The declared subr length must lie within the cleartext buffer. */
+ if (subr_length < 0 || subr_length > cleartext_end - subr_string)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
np = NULL;
np_length = 0;
/* Skip binary data and | or NP token. */
p = skip_token (subr_string + subr_length, cleartext_end);
if (p == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
while (p < cleartext_end && _cairo_isspace(*p))
p++;
/* Some fonts have "noaccess put" instead of "NP" */
if (p + 3 < cleartext_end && strncmp (p, "put", 3) == 0) {
p = skip_token (p, cleartext_end);
+ if (p == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
while (p < cleartext_end && _cairo_isspace(*p))
p++;
np = subr_string + subr_length;
np_length = p - np;
}
status = func (font, subr_num,
@@ -1241,25 +1252,34 @@ cairo_type1_font_subset_for_each_glyph (
* since the binary data could contain a '/'.
*/
p = dict_start;
glyph_count = 0;
while (*p == '/') {
name = p + 1;
p = skip_token (p, dict_end);
+ if (p == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
name_length = p - name;
charstring_length = strtol (p, &end, 10);
if (p == end)
return CAIRO_INT_STATUS_UNSUPPORTED;
/* Skip past -| or RD to binary data. There is exactly one space
* between the -| or RD token and the encrypted data, thus '+ 1'. */
- charstring = skip_token (end, dict_end) + 1;
+ charstring = skip_token (end, dict_end);
+ if (charstring == NULL)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+ charstring++;
+
+ /* The declared charstring length must lie within the cleartext buffer. */
+ if (charstring_length < 0 || charstring_length > dict_end - charstring)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
/* Skip binary data and |- or ND token. */
p = skip_token (charstring + charstring_length, dict_end);
if (p == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
while (p < dict_end && _cairo_isspace(*p))
p++;