Beispiel #1
0
/* Note that .setdevice clears the current pagedevice. */
int
zsetdevice(i_ctx_t *i_ctx_p)
{
    gx_device *dev = gs_currentdevice(igs);
    os_ptr op = osp;
    int code = 0;

    check_write_type(*op, t_device);
    if (dev->LockSafetyParams) {	  /* do additional checking if locked  */
        if(op->value.pdevice != dev) 	  /* don't allow a different device    */
	    return_error(e_invalidaccess);
    }
#ifndef PSI_INCLUDED
    /* the language switching build shouldn't install a new device
       here.  The language switching machinery installs a shared
       device. */

    code = gs_setdevice_no_erase(igs, op->value.pdevice);
#endif
    if (code < 0)
	return code;
    make_bool(op, code != 0);	/* erase page if 1 */
    clear_pagedevice(istate);
    return code;
}
Beispiel #2
0
static int
type1crypt(i_ctx_t *i_ctx_p,
           int (*proc)(byte *, const byte *, uint, ushort *))
{
    os_ptr op = osp;
    crypt_state state;
    uint ssize;

    check_type(op[-2], t_integer);
    state = op[-2].value.intval;
    if (op[-2].value.intval != state)
        return_error(e_rangecheck);	/* state value was truncated */
    check_read_type(op[-1], t_string);
    check_write_type(*op, t_string);
    ssize = r_size(op - 1);
    if (r_size(op) < ssize)
        return_error(e_rangecheck);
    discard((*proc)(op->value.bytes, op[-1].value.const_bytes, ssize,
                    &state));	/* can't fail */
    op[-2].value.intval = state;
    op[-1] = *op;
    r_set_size(op - 1, ssize);
    pop(1);
    return 0;
}
Beispiel #3
0
static int
zreadstring_at(i_ctx_t *i_ctx_p, os_ptr op, uint start)
{
    stream *s;
    uint len, rlen;
    int status;

    check_write_type(*op, t_string);
    check_read_file(s, op - 1);
    len = r_size(op);
    status = sgets(s, op->value.bytes + start, len - start, &rlen);
    rlen += start;
    switch (status) {
	case EOFC:
	case 0:
	    break;
	default:
	    return handle_read_status(i_ctx_p, status, op - 1, &rlen,
				      zreadstring_continue);
    }
    /*
     * The most recent Adobe specification says that readstring
     * must signal a rangecheck if the string length is zero.
     * I can't imagine the motivation for this, but we emulate it.
     * It's safe to check it here, rather than earlier, because if
     * len is zero, sgets will return 0 immediately with rlen = 0.
     */
    if (len == 0)
	return_error(e_rangecheck);
    r_set_size(op, rlen);
    op[-1] = *op;
    make_bool(op, (rlen == len ? 1 : 0));
    return 0;
}
Beispiel #4
0
/* Get some double arguments, and check for a double result. */
static int
double_params_result(os_ptr op, int count, double *pval)
{
    check_write_type(*op, t_string);
    if (r_size(op) != sizeof(double))
	return_error(e_typecheck);
    return double_params(op - 1, count, pval);
}
Beispiel #5
0
static int
zreadhexstring(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_write_type(*op, t_string);
    return zreadhexstring_at(i_ctx_p, op, 0, -1);
}
/* the dictionary parameter for the BoundedHuffman filters. */
static int
zcomputecodes(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    uint asize;
    hc_definition def;
    ushort *data;
    long *freqs;
    int code = 0;

    check_type(*op, t_integer);
    check_write_type(*op1, t_array);
    asize = r_size(op1);
    if (op->value.intval < 1 || op->value.intval > max_hc_length)
        return_error(e_rangecheck);
    def.num_counts = op->value.intval;
    if (asize < def.num_counts + 2)
        return_error(e_rangecheck);
    def.num_values = asize - (def.num_counts + 1);
    data = (ushort *) gs_alloc_byte_array(imemory, asize, sizeof(ushort),
                                          "zcomputecodes");
    freqs = (long *)gs_alloc_byte_array(imemory, def.num_values,
                                        sizeof(long),
                                        "zcomputecodes(freqs)");

    if (data == 0 || freqs == 0)
        code = gs_note_error(e_VMerror);
    else {
        uint i;

        def.counts = data;
        def.values = data + (def.num_counts + 1);
        for (i = 0; i < def.num_values; i++) {
            const ref *pf = op1->value.const_refs + i + def.num_counts + 1;

            if (!r_has_type(pf, t_integer)) {
                code = gs_note_error(e_typecheck);
                break;
            }
            freqs[i] = pf->value.intval;
        }
        if (!code) {
            code = hc_compute(&def, freqs, imemory);
            if (code >= 0) {
                /* Copy back results. */
                for (i = 0; i < asize; i++)
                    make_int(op1->value.refs + i, data[i]);
            }
        }
    }
    gs_free_object(imemory, freqs, "zcomputecodes(freqs)");
    gs_free_object(imemory, data, "zcomputecodes");
    if (code < 0)
        return code;
    pop(1);
    return code;
}
Beispiel #7
0
/* <any> <string> cvs <substring> */
static int
zcvs(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;

    check_write_type(*op, t_string);
    check_op(2);
    code = convert_to_string(imemory, op - 1, op);
    if (code >= 0)
	pop(1);
    return code;
}
Beispiel #8
0
/* <dnum> <string> .dcvs <substring> */
static int
zdcvs(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double num;
    int code = double_params(op - 1, 1, &num);
    char dot, str[MAX_CHARS + 1];
    int len;

    if (code < 0)
	return code;
    check_write_type(*op, t_string);
    sprintf(str, "%f", 1.5);
    dot = str[1]; /* locale-dependent */
    /*
     * To get fully accurate output results for IEEE double-
     * precision floats (53 bits of mantissa), the ANSI
     * %g default of 6 digits is not enough; 16 are needed.
     * Unfortunately, using %.16g produces unfortunate artifacts such as
     * 1.2 printing as 1.200000000000005.  Therefore, we print using %g,
     * and if the result isn't accurate enough, print again
     * using %.16g.
     */
    {
	double scanned;

	sprintf(str, "%g", num);
	sscanf(str, "%lf", &scanned);
	if (scanned != num)
	    sprintf(str, "%.16g", num);
    }
    len = strlen(str);
    if (len > r_size(op))
	return_error(e_rangecheck);
    /* Juggling locales isn't thread-safe. Posix me harder. */
    if (dot != '.') {
        char *pdot = strchr(str, dot); 
        if (pdot)
            *pdot = '.';
    }
    memcpy(op->value.bytes, str, len);
    op[-1] = *op;
    r_set_size(op - 1, len);
    pop(1);
    return 0;
}
Beispiel #9
0
/* *op contains the index within the string and the odd flag. */
static int
zreadhexstring_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code, length, odd;

    check_type(*op, t_integer);
    length = op->value.intval & 0xFFFFFF;
    odd = op->value.intval >> 24;
    
    if (length > r_size(op - 1) || odd < -1 || odd > 0xF)
	return_error(e_rangecheck);
    check_write_type(op[-1], t_string);
    code = zreadhexstring_at(i_ctx_p, op - 1, (uint)length, odd);
    if (code >= 0)
	pop(1);
    return code;
}
Beispiel #10
0
static int
zfilenameforall(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    file_enum *pfen;
    gx_io_device *iodev = NULL;
    gs_parsed_file_name_t pname;
    int code = 0;

    check_write_type(*op, t_string);
    check_proc(op[-1]);
    check_read_type(op[-2], t_string);
    /* Push a mark, the iodev, devicenamelen, the scratch string, the enumerator, */
    /* and the procedure, and invoke the continuation. */
    check_estack(7);
    /* Get the iodevice */
    code = parse_file_name(op - 2, &pname, i_ctx_p->LockFilePermissions);
    if (code < 0)
	return code;
    iodev = (pname.iodev == NULL) ? iodev_default : pname.iodev;

    /* Check for several conditions that just cause us to return success */
    if (pname.len == 0 || iodev->procs.enumerate_files == iodev_no_enumerate_files) {
        pop(3);
        return 0;	/* no pattern, or device not found -- just return */
    }
    pfen = iodev->procs.enumerate_files(iodev, (const char *)pname.fname,
    		pname.len, imemory);
    if (pfen == 0)
	return_error(e_VMerror);
    push_mark_estack(es_for, file_cleanup);
    ++esp;
    make_istruct(esp, 0, iodev);
    ++esp;
    make_int(esp, r_size(op-2) - pname.len);
    *++esp = *op;
    ++esp;
    make_istruct(esp, 0, pfen);
    *++esp = op[-1];
    pop(3);
    code = file_continue(i_ctx_p);
    return (code == o_pop_estack ? o_push_estack : code);
}
Beispiel #11
0
static int
zbosobject(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;

    check_type(op[-3], t_integer);
    check_type(op[-2], t_integer);
    check_write_type(*op, t_string);
    if (r_size(op) < 8)
        return_error(gs_error_rangecheck);
    code = encode_binary_token(i_ctx_p, op - 1, &op[-3].value.intval,
                               &op[-2].value.intval, op->value.bytes);
    if (code < 0)
        return code;
    op[-1] = *op;
    r_set_size(op - 1, 8);
    pop(1);
    return 0;
}
Beispiel #12
0
/* <file> <string> .peekstring <substring> <filled_bool> */
static int
zpeekstring(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    stream *s;
    uint len, rlen;

    check_read_file(s, op - 1);
    check_write_type(*op, t_string);
    len = r_size(op);
    while ((rlen = sbufavailable(s)) < len) {
	int status = s->end_status;

	switch (status) {
	case EOFC:
	    break;
	case 0:
	    /*
	     * The following is a HACK.  It should reallocate the buffer to hold
	     * at least len bytes.  However, this raises messy problems about
	     * which allocator to use and how it should interact with restore.
	     */
	    if (len >= s->bsize)
		return_error(e_rangecheck);
	    s_process_read_buf(s);
	    continue;
	default:
	    return handle_read_status(i_ctx_p, status, op - 1, NULL,
				      zpeekstring);
	}
	break;
    }
    if (rlen > len)
	rlen = len;
    /* Don't remove the data from the buffer. */
    memcpy(op->value.bytes, sbufptr(s), rlen);
    r_set_size(op, rlen);
    op[-1] = *op;
    make_bool(op, (rlen == len ? 1 : 0));
    return 0;
}
Beispiel #13
0
/* Return 0 if OK, error code if not. */
int
write_matrix_in(ref * op, const gs_matrix * pmat, gs_dual_memory_t *idmemory,
		gs_ref_memory_t *imem)
{
    ref *aptr;
    const float *pel;
    int i;

    check_write_type(*op, t_array);
    if (r_size(op) != 6)
	return_error(e_rangecheck);
    aptr = op->value.refs;
    pel = (const float *)pmat;
    for (i = 5; i >= 0; i--, aptr++, pel++) {
	if (idmemory) {
	    ref_save(op, aptr, "write_matrix");
	    make_real_new(aptr, *pel);
	} else {
	    make_tav(aptr, t_real, imemory_new_mask(imem), realval, *pel);
	}
    }
    return 0;
}
Beispiel #14
0
/*
 * We could handle readline the same way as readstring,
 * except for the anomalous situation where we get interrupted
 * between the CR and the LF of an end-of-line marker.
 * We hack around this in the following way: if we get interrupted
 * before we've read any characters, we just restart the readline;
 * if we get interrupted at any other time, we use readline_continue;
 * we use start=0 (which we have just ruled out as a possible start value
 * for readline_continue) to indicate interruption after the CR.
 */
static int
zreadline_at(i_ctx_t *i_ctx_p, os_ptr op, uint count, bool in_eol)
{
    stream *s;
    int status;
    gs_string str;

    check_write_type(*op, t_string);
    check_read_file(s, op - 1);
    str.data = op->value.bytes;
    str.size = r_size(op);
    status = zreadline_from(s, &str, NULL, &count, &in_eol);
    switch (status) {
	case 0:
	case EOFC:
	    break;
	case 1:
	    return_error(e_rangecheck);
	default:
	    if (count == 0 && !in_eol)
		return handle_read_status(i_ctx_p, status, op - 1, NULL,
					  zreadline);
	    else {
		if (in_eol) {
		    r_set_size(op, count);
		    count = 0;
		}
		return handle_read_status(i_ctx_p, status, op - 1, &count,
					  zreadline_continue);
	    }
    }
    r_set_size(op, count);
    op[-1] = *op;
    make_bool(op, status == 0);
    return 0;
}
Beispiel #15
0
/*   .getbitsrect <height> <substring> */
static int
zgetbitsrect(i_ctx_t *i_ctx_p)
{	/*
	 * alpha? is 0 for no alpha, -1 for alpha first, 1 for alpha last.
	 * std_depth is null for native pixels, depth/component for
	 * standard color space.
	 */
    os_ptr op = osp;
    gx_device *dev;
    gs_int_rect rect;
    gs_get_bits_params_t params;
    int w, h;
    gs_get_bits_options_t options =
	GB_ALIGN_ANY | GB_RETURN_COPY | GB_OFFSET_0 | GB_RASTER_STANDARD |
	GB_PACKING_CHUNKY;
    int depth;
    uint raster;
    int num_rows;
    int code;

    check_read_type(op[-7], t_device);
    dev = op[-7].value.pdevice;
    check_int_leu(op[-6], dev->width);
    rect.p.x = op[-6].value.intval;
    check_int_leu(op[-5], dev->height);
    rect.p.y = op[-5].value.intval;
    check_int_leu(op[-4], dev->width);
    w = op[-4].value.intval;
    check_int_leu(op[-3], dev->height);
    h = op[-3].value.intval;
    check_type(op[-2], t_integer);
    /*
     * We use if/else rather than switch because the value is long,
     * which is not supported as a switch value in pre-ANSI C.
     */
    if (op[-2].value.intval == -1)
	options |= GB_ALPHA_FIRST;
    else if (op[-2].value.intval == 0)
	options |= GB_ALPHA_NONE;
    else if (op[-2].value.intval == 1)
	options |= GB_ALPHA_LAST;
    else
	return_error(e_rangecheck);
    if (r_has_type(op - 1, t_null)) {
	options |= GB_COLORS_NATIVE;
	depth = dev->color_info.depth;
    } else {
	static const gs_get_bits_options_t depths[17] = {
	    0, GB_DEPTH_1, GB_DEPTH_2, 0, GB_DEPTH_4, 0, 0, 0, GB_DEPTH_8,
	    0, 0, 0, GB_DEPTH_12, 0, 0, 0, GB_DEPTH_16
	};
	gs_get_bits_options_t depth_option;
	int std_depth;

	check_int_leu(op[-1], 16);
	std_depth = (int)op[-1].value.intval;
	depth_option = depths[std_depth];
	if (depth_option == 0)
	    return_error(e_rangecheck);
	options |= depth_option | GB_COLORS_NATIVE;
	depth = (dev->color_info.num_components +
		 (options & GB_ALPHA_NONE ? 0 : 1)) * std_depth;
    }
    if (w == 0)
	return_error(e_rangecheck);
    raster = (w * depth + 7) >> 3;
    check_write_type(*op, t_string);
    num_rows = r_size(op) / raster;
    h = min(h, num_rows);
    if (h == 0)
	return_error(e_rangecheck);
    rect.q.x = rect.p.x + w;
    rect.q.y = rect.p.y + h;
    params.options = options;
    params.data[0] = op->value.bytes;
    code = (*dev_proc(dev, get_bits_rectangle))(dev, &rect, &params, NULL);
    if (code < 0)
	return code;
    make_int(op - 7, h);
    op[-6] = *op;
    r_set_size(op - 6, h * raster);
    pop(6);
    return 0;
}
Beispiel #16
0
/*   <bitmap> <cid> <type32font> <str22> .makeglyph32 <<same with substr>> */
static int
zmakeglyph32(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    bool long_form;
    uint msize;
    double metrics[10];
    int wx, llx, lly, urx, ury;
    int width, height, raster;
    gs_font *pfont;
    int code;
    byte *str;

    check_array(op[-4]);
    msize = r_size(op - 4);
    switch (msize) {
        case 10:
            long_form = true;
            break;
        case 6:
            long_form = false;
            break;
        default:
            return_error(gs_error_rangecheck);
    }
    code = num_params(op[-4].value.refs + msize - 1, msize, metrics);
    if (code < 0)
        return code;
    if (~code & 0x3c)		/* check llx .. ury for integers */
        return_error(gs_error_typecheck);
    check_read_type(op[-3], t_string);
    llx = (int)metrics[2];
    lly = (int)metrics[3];
    urx = (int)metrics[4];
    ury = (int)metrics[5];
    width = urx - llx;
    height = ury - lly;
    raster = (width + 7) >> 3;
    if (width < 0 || height < 0 || r_size(op - 3) != raster * height)
        return_error(gs_error_rangecheck);
    check_int_leu(op[-2], 65535);
    code = font_param(op - 1, &pfont);
    if (code < 0)
        return code;
    if (pfont->FontType != ft_CID_bitmap)
        return_error(gs_error_invalidfont);
    check_write_type(*op, t_string);
    if (r_size(op) < 22)
        return_error(gs_error_rangecheck);
    str = op->value.bytes;
    if (long_form || metrics[0] != (wx = (int)metrics[0]) ||
        metrics[1] != 0 || height == 0 ||
        ((wx | width | height | (llx + 128) | (lly + 128)) & ~255) != 0
        ) {
        /* Use the long form. */
        int i, n = (long_form ? 10 : 6);

        str[0] = 0;
        str[1] = long_form;
        for (i = 0; i < n; ++i) {
            int v = (int)metrics[i];  /* no floating point widths yet */

            str[2 + 2 * i] = (byte)(v >> 8);
            str[2 + 2 * i + 1] = (byte)v;
        }
        r_set_size(op, 2 + n * 2);
    } else {
Beispiel #17
0
/* <num> <radix_int> <string> cvrs <substring> */
static int
zcvrs(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int radix;

    check_type(op[-1], t_integer);
    if (op[-1].value.intval < 2 || op[-1].value.intval > 36)
	return_error(e_rangecheck);
    radix = op[-1].value.intval;
    check_write_type(*op, t_string);
    if (radix == 10) {
	switch (r_type(op - 2)) {
	    case t_integer:
	    case t_real:
		{
		    int code = convert_to_string(imemory, op - 2, op);

		    if (code < 0)
			return code;
		    pop(2);
		    return 0;
		}
            case t__invalid:
                return_error(e_stackunderflow);
	    default:
		return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
	}
    } else {
	uint ival;
	byte digits[sizeof(ulong) * 8];
	byte *endp = &digits[countof(digits)];
	byte *dp = endp;

	switch (r_type(op - 2)) {
	    case t_integer:
		ival = (uint) op[-2].value.intval;
		break;
	    case t_real:
		{
		    float fval = op[-2].value.realval;

		    if (!REAL_CAN_BE_INT(fval))
			return_error(e_rangecheck);
		    ival = (ulong) (long)fval;
		} break;
            case t__invalid:
                return_error(e_stackunderflow);
	    default:
		return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
	}
	do {
	    int dit = ival % radix;

	    *--dp = dit + (dit < 10 ? '0' : ('A' - 10));
	    ival /= radix;
	}
	while (ival);
	if (endp - dp > r_size(op))
	    return_error(e_rangecheck);
	memcpy(op->value.bytes, dp, (uint) (endp - dp));
	r_set_size(op, endp - dp);
    }
    op[-2] = *op;
    pop(2);
    return 0;
}