summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2012-05-25 14:12:37 +0100
committerKen Sharp <ken.sharp@artifex.com>2012-05-25 14:12:37 +0100
commitc6f9e998b9ab277f85815b927a841c26c507928a (patch)
tree939d2dc2601727dc3b2b879bd26dd18b407b0931
parent9f656faebac150c6aceca16c5ef6a78b92b6da43 (diff)
pdfwrite - fix /OtherSubr stripping with Multiple Master fonts
Commit: 9f656faebac150c6aceca16c5ef6a78b92b6da43 exposed a problem with this code, when we are stripping /OtherSubrs from MM fonts, the new CharString could be larger than the original (this can't happen for non-MM fonts). Because we only allocated a buffer big enough to hold the original (unstripped) data, we ended up with a buffer overflow. The code now calls the 'strip' routine twice, the first time to calculate how big a buffer will be required, the second time to actually do the work. This will fix the crash in test-setweightvector.ps introduced by the earlier commit
-rw-r--r--gs/base/gdevpsf1.c83
1 files changed, 61 insertions, 22 deletions
diff --git a/gs/base/gdevpsf1.c b/gs/base/gdevpsf1.c
index 6b8d84090..f63ceec89 100644
--- a/gs/base/gdevpsf1.c
+++ b/gs/base/gdevpsf1.c
@@ -310,12 +310,21 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
gs_bytestring *data = (gs_bytestring *)&gdata->bits;
byte *source = data->data, *dest = stripped, *end = source + data->size;
int i, dest_length = 0, CurrentNumberIndex = 0, Stack[64], written;
+ int OnlyCalcLength = 0;
+ char Buffer[16];
+
+ if (stripped == NULL) {
+ OnlyCalcLength = 1;
+ dest = (byte *)&Buffer;
+ }
gs_type1_decrypt(source, source, data->size, &state);
if(pfont->data.lenIV >= 0) {
- for (i=0;i<pfont->data.lenIV;i++)
- *dest++ = *source++;
+ for (i=0;i<pfont->data.lenIV;i++) {
+ if (!OnlyCalcLength)
+ *dest++ = *source++;
+ }
dest_length += pfont->data.lenIV;
}
while (source < end) {
@@ -338,7 +347,8 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
source += 2;
break;
@@ -347,7 +357,8 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
source += 2;
break;
@@ -356,7 +367,8 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
source += 2;
break;
@@ -365,7 +377,8 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
source += 2;
break;
@@ -374,7 +387,8 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
source += 2;
break;
@@ -382,10 +396,15 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
+ }
+ if (!OnlyCalcLength) {
+ *dest++ = *source++;
+ *dest++ = *source++;
+ } else {
+ source += 2;
}
- *dest++ = *source++;
- *dest++ = *source++;
dest_length += 2;
break;
}
@@ -393,10 +412,15 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
+ }
+ if (!OnlyCalcLength) {
+ *dest++ = *source++;
+ *dest++ = *source++;
+ } else {
+ source += 2;
}
- *dest++ = *source++;
- *dest++ = *source++;
dest_length += 2;
}
break;
@@ -410,21 +434,27 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i=0;i < StackBase; i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
for (i=0;i<SubrsWithMM[index];i++) {
written = WriteNumber(dest, Stack[StackBase + i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
source++;
} else {
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
- *dest++ = *source++;
+ if (!OnlyCalcLength)
+ *dest++ = *source++;
+ else
+ source++;
dest_length++;
}
break;
@@ -432,9 +462,13 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
for (i = 0;i < CurrentNumberIndex;i++) {
written = WriteNumber(dest, Stack[i]);
dest_length += written;
- dest += written;
+ if (!OnlyCalcLength)
+ dest += written;
}
- *dest++ = *source++;
+ if (!OnlyCalcLength)
+ *dest++ = *source++;
+ else
+ source++;
dest_length++;
}
CurrentNumberIndex = 0;
@@ -464,8 +498,11 @@ static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *
source = data->data;
state = crypt_charstring_seed;
gs_type1_encrypt(source, source, data->size, &state);
- state = crypt_charstring_seed;
- gs_type1_encrypt(stripped, stripped, dest_length, &state);
+
+ if (!OnlyCalcLength) {
+ state = crypt_charstring_seed;
+ gs_type1_encrypt(stripped, stripped, dest_length, &state);
+ }
return dest_length;
}
@@ -597,9 +634,11 @@ write_Private(stream *s, gs_font_type1 *pfont,
if (gdata.bits.size) {
if (pfont->data.WeightVector.count != 0) {
byte *stripped;
+ int length;
gs_bytestring *data = (gs_bytestring *)&gdata.bits;
- stripped = gs_alloc_bytes(pfont->memory, data->size, "Subrs copy for OtherSubrs");
+ length = strip_othersubrs(&gdata, pfont, NULL, SubrsWithMM);
+ stripped = gs_alloc_bytes(pfont->memory, length, "Subrs copy for OtherSubrs");
code = strip_othersubrs(&gdata, pfont, stripped, SubrsWithMM);
if (code < 0) {
if (SubrsWithMM != 0)