summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gstype42.c')
-rw-r--r--base/gstype42.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/base/gstype42.c b/base/gstype42.c
index 3cc92213..5ef1c227 100644
--- a/base/gstype42.c
+++ b/base/gstype42.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -68,6 +68,8 @@ font_proc_font_info(gs_truetype_font_info); /* Type check. */
#define PUTU16(p, n, offs) {(p + offs)[0] = n >> 8 & 255; (p + offs)[1] = n & 255;}
+static byte const ver10[4] = {0x00, 0x01, 0x00, 0x00};
+static byte const ver20[4] = {0x00, 0x02, 0x00, 0x00};
/* ---------------- Font level ---------------- */
@@ -207,7 +209,14 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID)
if (!memcmp(tab, "cmap", 4))
pfont->data.cmap = offset;
else if (!memcmp(tab, "post", 4)) {
- pfont->data.post_offset = offset;
+ byte ver[4];
+ READ_SFNTS(pfont, offset, 4, ver);
+ if (memcmp(ver, ver10, 4) == 0 || memcmp(ver, ver20, 4) == 0) {
+ pfont->data.post_offset = offset;
+ }
+ else {
+ pfont->data.post_offset = 0;
+ }
}
else if (!memcmp(tab, "glyf", 4)) {
pfont->data.glyf = offset;
@@ -269,8 +278,13 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID)
pfont->data.os2_offset = offset;
}
}
- loca_size >>= pfont->data.indexToLocFormat + 1;
+ loca_size >>= (pfont->data.indexToLocFormat == 0 ? 1 : 2);
pfont->data.numGlyphs = loca_size - 1;
+ if (pfont->data.numGlyphs > 65535) {
+ pfont->data.numGlyphs = 65535;
+ loca_size = (65536 << (pfont->data.indexToLocFormat == 0 ? 1 : 2));
+ }
+
if (pfont->data.numGlyphs > (int)pfont->data.trueNumGlyphs) {
/* pfont->key_name.chars is ASCIIZ due to copy_font_name. */
char buf[gs_font_name_max + 2];
@@ -403,8 +417,10 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID)
qsort(psortary, loca_size, sizeof(gs_type42_font_init_sort_t), gs_type42_font_init_compare);
while (num_valid_loca_elm > 0 && psortary[num_valid_loca_elm - 1].glyph_offset > glyph_size)
num_valid_loca_elm --;
- if (0 == num_valid_loca_elm)
+ if (0 == num_valid_loca_elm) {
+ gs_free_object(pfont->memory, psortary, "gs_type42_font_init(sort loca)");
return_error(gs_error_invalidfont);
+ }
for (i = num_valid_loca_elm; i--;) {
long old_length;
@@ -754,8 +770,6 @@ gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gnam
if (pfont->FontType == ft_TrueType) {
if (pfont->data.post_offset != 0) {
byte ver[4];
- byte const ver10[4] = {0x00, 0x01, 0x00, 0x00};
- byte const ver20[4] = {0x00, 0x02, 0x00, 0x00};
READ_SFNTS(pfont, pfont->data.post_offset, 4, ver);
if (!memcmp(ver, ver10, 4)){
@@ -801,6 +815,9 @@ gs_type42_find_post_name(gs_font_type42 * pfont, gs_glyph glyph, gs_string *gnam
}
}
}
+ else {
+ code2 = gs_error_invalidfont;
+ }
}
}
else
@@ -1283,8 +1300,13 @@ parse_pieces(gs_font_type42 *pfont, gs_glyph glyph, gs_glyph *pieces,
memset(&mat, 0, sizeof(mat)); /* arbitrary */
for (i = 0; flags & TT_CG_MORE_COMPONENTS; ++i) {
- if (pieces)
+ if (pieces) {
pieces[i] = U16(gdata + 2) + GS_MIN_GLYPH_INDEX;
+ if (U16(gdata + 2) > pfont->data.numGlyphs) {
+ *pnum_pieces = 0;
+ return_error(gs_error_invalidfont);
+ }
+ }
gs_type42_parse_component(&gdata, &flags, &mat, NULL, pfont, &mat);
}
*pnum_pieces = i;