Exemplo n.º 1
0
/* convenience of reusing procedures that take 1 state parameter */
static int
zreadhexstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start, int odd)
{
    stream *s;
    uint len, nread;
    byte *str;
    int odd_byte = odd;
    stream_cursor_write cw;
    int status;

    check_read_file(s, op - 1);
    /*check_write_type(*op, t_string); *//* done by caller */
    str = op->value.bytes;
    len = r_size(op);
    cw.ptr = str + start - 1;
    cw.limit = str + len - 1;
    for (;;) {
	status = s_hex_process(&s->cursor.r, &cw, &odd_byte,
			       hex_ignore_garbage);
	if (status == 1) {	/* filled the string */
	    ref_assign_inline(op - 1, op);
	    make_true(op);
	    return 0;
	} else if (status != 0)	/* error or EOF */
	    break;
	/* Didn't fill, keep going. */
	status = spgetc(s);
	if (status < 0)
	    break;
	sputback(s);
    }
    nread = cw.ptr + 1 - str;
    if (status != EOFC) {	/* Error */
	nread |= odd_byte << 24;
        return handle_read_status(i_ctx_p, status, op - 1, &nread,
				  zreadhexstring_continue);
    }
    /* Reached end-of-file before filling the string. */
    /* Return an appropriate substring. */
    ref_assign_inline(op - 1, op);
    r_set_size(op - 1, nread);
    make_false(op);
    return 0;
}
Exemplo n.º 2
0
/* Process a buffer. */
static int
s_exD_process(stream_state * st, stream_cursor_read * pr,
              stream_cursor_write * pw, bool last)
{
    stream_exD_state *const ss = (stream_exD_state *) st;
    const byte *p = pr->ptr;
    byte *q = pw->ptr;
    int skip = ss->skip;
    int rcount = pr->limit - p;
    int wcount = pw->limit - q;
    int status = 0;
    int count = (wcount < rcount ? (status = 1, wcount) : rcount);

    if (ss->binary < 0) {
        /*
         * This is the very first time we're filling the buffer.
         */
        const byte *const decoder = scan_char_decoder;
        int i;

        if (ss->pfb_state == 0 && !ss->keep_spaces) {
            /*
             * Skip '\t', '\r', '\n', ' ' at the beginning of the input stream,
             * because Adobe PS interpreters do this. Don't skip '\0' or '\f'.
             * Acrobat Reader doesn't skip spaces at all.
             */
            for (; rcount; rcount--, p++) {
                byte c = p[1];
                if(c != '\t' && c != char_CR && c != char_EOL && c != ' ')
                    break;
            }
            pr->ptr = p;
            count = min(wcount, rcount);
        }

        /*
         * Determine whether this is ASCII or hex encoding.
         * Adobe's documentation doesn't actually specify the test
         * that eexec should use, but we believe the following
         * gives correct answers even on certain non-conforming
         * PostScript files encountered in practice:
         */
        if (rcount < 8 && !last)
            return 0;

        ss->binary = 0;
        for (i = min(8, rcount); i > 0; i--)
            if (!(decoder[p[i]] <= 0xf ||
                  decoder[p[i]] == ctype_space)
                ) {
                ss->binary = 1;
                break;
            }
    }
    if (ss->binary) {
        /*
         * There is no need to pause at the end of the binary portion.
         * The padding bytes (which are in the text portion, in hexadecimal)
         * do their job, provided the write buffer is <= 256 bytes long.
         * This is (hopefully) ensured by the comment just above the
         * definition of s_exD_template.
         */
        pr->ptr = p + count;
    } else {
        /*
         * We only ignore leading whitespace, in an attempt to
         * keep from reading beyond the end of the encrypted data;
         * but some badly coded files require us to ignore % also.
         */
        stream_cursor_read r;
        const byte *start;

hp:	r = *pr;
        start = r.ptr;
        if (r.limit - r.ptr > ss->hex_left)
            r.limit = r.ptr + ss->hex_left;
        status = s_hex_process(&r, pw, &ss->odd,
          (ss->is_leading_space ? hex_ignore_leading_whitespace : hex_break_on_whitespace));
        if (status == 2) {
            ss->is_leading_space = true;
            status = 1;
        } else
            ss->is_leading_space = false;
        pr->ptr = r.ptr;
        ss->hex_left -= r.ptr - start;
        /*
         * Check for having finished a prematurely decoded hex section of
         * a PFB file.
         */
        if (ss->hex_left == 0)
            ss->binary = 1;
        count = pw->ptr - q;
        if (status < 0 && ss->odd < 0) {
            if (count) {
                --p;
                status = 0;	/* reprocess error next time */
            } else if (*p == '%')
                goto hp;	/* ignore % */
        }
        p = q;
    }
    if (skip >= count && skip != 0) {
        gs_type1_decrypt(q + 1, p + 1, count,
                         (crypt_state *) & ss->cstate);
        ss->skip -= count;
        count = 0;
        status = 0;
    } else {
        gs_type1_decrypt(q + 1, p + 1, skip,
                         (crypt_state *) & ss->cstate);
        count -= skip;
        gs_type1_decrypt(q + 1, p + 1 + skip, count,
                         (crypt_state *) & ss->cstate);
        ss->skip = 0;
    }
    pw->ptr = q + count;
    return status;
}