Exemplo n.º 1
0
static int
charstring_make_notdef(gs_glyph_data_t *pgd, gs_font *font)
{
    gs_font_type1 *const pfont = (gs_font_type1 *)font;
    static const byte char_data[4] = {
        139,			/* 0 */
        139,			/* 0 */
        c1_hsbw,
        cx_endchar
    };
    uint len = max(pfont->data.lenIV, 0) + sizeof(char_data);
    byte *chars = gs_alloc_string(font->memory, len, "charstring_make_notdef");

    if (chars == 0)
        return_error(e_VMerror);
    gs_glyph_data_from_string(pgd, chars, len, font);
    if (pfont->data.lenIV < 0)
        memcpy(chars, char_data, sizeof(char_data));
    else {
        crypt_state state = crypt_charstring_seed;

        memcpy(chars + pfont->data.lenIV, char_data, sizeof(char_data));
        gs_type1_encrypt(chars, chars, len, &state);
    }
    return 0;
}
Exemplo n.º 2
0
/* Encrypt and write a CharString. */
static int
stream_write_encrypted(stream *s, const void *ptr, uint count)
{
    const byte *const data = ptr;
    crypt_state state = crypt_charstring_seed;
    byte buf[50];		/* arbitrary */
    uint left, n;
    int code = 0;

    for (left = count; left > 0; left -= n) {
	n = min(left, sizeof(buf));
	gs_type1_encrypt(buf, data + count - left, n, &state);
	code = stream_write(s, buf, n);
    }
    return code;
}
Exemplo n.º 3
0
/* Process a buffer */
static int
s_exE_process(stream_state * st, stream_cursor_read * pr,
              stream_cursor_write * pw, bool last)
{
    stream_exE_state *const ss = (stream_exE_state *) st;
    const byte *p = pr->ptr;
    byte *q = pw->ptr;
    uint rcount = pr->limit - p;
    uint wcount = pw->limit - q;
    uint count;
    int status;

    if (rcount <= wcount)
        count = rcount, status = 0;
    else
        count = wcount, status = 1;
    gs_type1_encrypt(q + 1, p + 1, count, (crypt_state *)&ss->cstate);
    pr->ptr += count;
    pw->ptr += count;
    return status;
}
Exemplo n.º 4
0
static int strip_othersubrs(gs_glyph_data_t *gdata, gs_font_type1 *pfont, byte *stripped, byte *SubrsWithMM)
{
    crypt_state state = crypt_charstring_seed;
    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];

    memset(Stack, 0x00, 64 * sizeof(int));
    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++) {
            if (!OnlyCalcLength)
                *dest++ = *source++;
        }
        dest_length += pfont->data.lenIV;
    }
    while (source < end) {
        if (*source < 32) {
            /* Command */
            switch (*source) {
                case 12:
                    if (*(source + 1) == 16) {
                        /* Callothersubsr, the only thing we care about */
                        switch(Stack[CurrentNumberIndex-1]) {
                            /* If we find a Multiple Master call, remove all but the
                             * first set of arguments. Mimics the result of a call.
                             * Adobe 'encourages' the use of Subrs to do MM, but
                             * the spec doens't say you have to, so we need to be
                             * prepared, just in case. I doubt we will ever execute
                             * this code.
                             */
                            case 14:
                                CurrentNumberIndex -= pfont->data.WeightVector.count - 1;
                                for (i = 0;i < CurrentNumberIndex;i++) {
                                    written = WriteNumber(dest, Stack[i]);
                                    dest_length += written;
                                    if (!OnlyCalcLength)
                                        dest += written;
                                }
                                source += 2;
                                break;
                            case 15:
                                CurrentNumberIndex -= (pfont->data.WeightVector.count - 1) * 2;
                                for (i = 0;i < CurrentNumberIndex;i++) {
                                    written = WriteNumber(dest, Stack[i]);
                                    dest_length += written;
                                    if (!OnlyCalcLength)
                                        dest += written;
                                }
                                source += 2;
                                break;
                            case 16:
                                CurrentNumberIndex -= (pfont->data.WeightVector.count - 1) * 3;
                                for (i = 0;i < CurrentNumberIndex;i++) {
                                    written = WriteNumber(dest, Stack[i]);
                                    dest_length += written;
                                    if (!OnlyCalcLength)
                                        dest += written;
                                }
                                source += 2;
                                break;
                            case 17:
                                CurrentNumberIndex -= (pfont->data.WeightVector.count - 1) * 4;
                                for (i = 0;i < CurrentNumberIndex;i++) {
                                    written = WriteNumber(dest, Stack[i]);
                                    dest_length += written;
                                    if (!OnlyCalcLength)
                                        dest += written;
                                }
                                source += 2;
                                break;
                            case 18:
                                CurrentNumberIndex -= (pfont->data.WeightVector.count - 1) * 6;
                                for (i = 0;i < CurrentNumberIndex;i++) {
                                    written = WriteNumber(dest, Stack[i]);
                                    dest_length += written;
                                    if (!OnlyCalcLength)
                                        dest += written;
                                }
                                source += 2;
                                break;
                            default:
                                for (i = 0;i < CurrentNumberIndex;i++) {
                                    written = WriteNumber(dest, Stack[i]);
                                    dest_length += written;
                                    if (!OnlyCalcLength)
                                        dest += written;
                                }
                                if (!OnlyCalcLength) {
                                    *dest++ = *source++;
                                    *dest++ = *source++;
                                } else {
                                    source += 2;
                                }
                                dest_length += 2;
                                break;
                        }
                    } else {
                        for (i = 0;i < CurrentNumberIndex;i++) {
                            written = WriteNumber(dest, Stack[i]);
                            dest_length += written;
                            if (!OnlyCalcLength)
                                dest += written;
                        }
                        if (!OnlyCalcLength) {
                            *dest++ = *source++;
                            *dest++ = *source++;
                        } else {
                            source += 2;
                        }
                        dest_length += 2;
                    }
                    break;
                case 10:
                    if (CurrentNumberIndex != 0 && SubrsWithMM[Stack[CurrentNumberIndex - 1]] != 0) {
                        int index = Stack[CurrentNumberIndex - 1];
                        int StackBase = CurrentNumberIndex - 1 - pfont->data.WeightVector.count * SubrsWithMM[index];

                        CurrentNumberIndex--; /* Remove the subr index */

                        for (i=0;i < StackBase; i++) {
                            written = WriteNumber(dest, Stack[i]);
                            dest_length += written;
                            if (!OnlyCalcLength)
                                dest += written;
                        }
                        for (i=0;i<SubrsWithMM[index];i++) {
                            written = WriteNumber(dest, Stack[StackBase + i]);
                            dest_length += written;
                            if (!OnlyCalcLength)
                                dest += written;
                        }
                        source++;
                    } else {
                        for (i = 0;i < CurrentNumberIndex;i++) {
                            written = WriteNumber(dest, Stack[i]);
                            dest_length += written;
                            if (!OnlyCalcLength)
                                dest += written;
                        }
                        if (!OnlyCalcLength)
                            *dest++ = *source++;
                        else
                            source++;
                        dest_length++;
                    }
                    break;
                default:
                    for (i = 0;i < CurrentNumberIndex;i++) {
                        written = WriteNumber(dest, Stack[i]);
                        dest_length += written;
                        if (!OnlyCalcLength)
                            dest += written;
                    }
                    if (!OnlyCalcLength)
                        *dest++ = *source++;
                    else
                        source++;
                    dest_length++;
            }
            CurrentNumberIndex = 0;
        } else {
            /* Number */
            if (*source < 247) {
                Stack[CurrentNumberIndex++] = *source++ - 139;
            } else {
                if (*source < 251) {
                    Stack[CurrentNumberIndex] = ((*source++ - 247) * 256) + 108;
                    Stack[CurrentNumberIndex++] += *source++;
                } else {
                    if (*source < 255) {
                        Stack[CurrentNumberIndex] = ((*source++ - 251) * -256) - 108;
                        Stack[CurrentNumberIndex++] -= *source++;
                    } else {
                        source++;
                        Stack[CurrentNumberIndex] = *source++ << 24;
                        Stack[CurrentNumberIndex] += *source++ << 16;
                        Stack[CurrentNumberIndex] += *source++ << 8;
                        Stack[CurrentNumberIndex++] += *source++;
                    }
                }
            }
        }
    }
    source = data->data;
    state = crypt_charstring_seed;
    gs_type1_encrypt(source, source, data->size, &state);

    if (!OnlyCalcLength) {
        state = crypt_charstring_seed;
        gs_type1_encrypt(stripped, stripped, dest_length, &state);
    }
    return dest_length;
}
Exemplo n.º 5
0
/* The following 2 routines attempt to parse out Multiple Master 'OtherSubrs'
 * calls, and replace the multiple arguments to $Blend with the two 'base'
 * parameters. This works reasonably well but can be defeated. FOr example a
 * CharString which puts some parameters on the operand stack, then calls a
 * Subr which puts the remaining parameters on the stack, and calls a MM
 * OtherSubr (constructions like this have been observed). In general we
 * work around this by storing the operands on the stack, but it is possible
 * that the values are calculated (eg x y div) which is a common way to get
 * float values into the interpreter. This will defeat the code below.
 *
 * The only way to solve this is to actually fully interpret the CharString
 * and any /Subrs it calls, and then emit the result as a non-MM CharString
 * by blending the values. This would mean writing a new routine like
 * 'psf_convert_type1_to_type2' (see gdevpsfx.c) or modifying that routine
 * so that it outputs type 1 CharStrings (which is probably simpler to do).
 */
static int CheckSubrForMM (gs_glyph_data_t *gdata, gs_font_type1 *pfont)
{
    crypt_state state = crypt_charstring_seed;
    int code = 0;
    gs_bytestring *data = (gs_bytestring *)&gdata->bits;
    byte *source = data->data, *end = source + data->size;
    int CurrentNumberIndex = 0, Stack[32];

    memset(Stack, 0x00, sizeof(Stack));
    gs_type1_decrypt(source, source, data->size, &state);

    if(pfont->data.lenIV)
        source += pfont->data.lenIV;

    while (source < end) {
        if (*source < 32) {
            /* Command */
            switch (*source) {
                case 12:
                    if (*(source + 1) == 16) {
                        if (CurrentNumberIndex < 1)
                            return gs_error_rangecheck;
                        switch(Stack[CurrentNumberIndex-1]) {
                            case 18:
                                code = 6;
                                break;
                            case 17:
                                code = 4;
                                break;
                            case 16:
                                code = 3;
                                break;
                            case 15:
                                code = 2;
                                break;
                            case 14:
                                code = 1;
                                break;
                            default:
                                code = 0;
                                break;
                        }
                        source += 2;
                    } else {
                        source +=2;
                    }
                    break;
                default:
                    source++;
                    break;
            }
            CurrentNumberIndex = 0;
        } else {
            /* Number */
            if (*source < 247) {
                Stack[CurrentNumberIndex++] = *source++ - 139;
            } else {
                if (*source < 251) {
                    Stack[CurrentNumberIndex] = ((*source++ - 247) * 256) + 108;
                    Stack[CurrentNumberIndex++] += *source++;
                } else {
                    if (*source < 255) {
                        Stack[CurrentNumberIndex] = ((*source++ - 251) * -256) - 108;
                        Stack[CurrentNumberIndex++] -= *source++;
                    } else {
                        Stack[CurrentNumberIndex] = *source++ << 24;
                        Stack[CurrentNumberIndex] += *source++ << 16;
                        Stack[CurrentNumberIndex] += *source++ << 8;
                        Stack[CurrentNumberIndex] += *source++;
                    }
                }
            }
        }
    }
    state = crypt_charstring_seed;
    source = data->data;
    gs_type1_encrypt(source, source, data->size, &state);
    return code;
}