diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2012-05-25 14:12:37 +0100 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2012-05-25 14:12:37 +0100 |
commit | c6f9e998b9ab277f85815b927a841c26c507928a (patch) | |
tree | 939d2dc2601727dc3b2b879bd26dd18b407b0931 | |
parent | 9f656faebac150c6aceca16c5ef6a78b92b6da43 (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.c | 83 |
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) |