示例#1
0
/* <obj1> ... <objn> <n> .execn - */
static int
zexecn(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint n, i;
    es_ptr esp_orig;

    check_int_leu(*op, max_uint - 1);
    n = (uint) op->value.intval;
    check_op(n + 1);
    check_estack(n);
    esp_orig = esp;
    for (i = 0; i < n; ++i) {
        const ref *rp = ref_stack_index(&o_stack, (long)(i + 1));

        /* Make sure this object is legal to execute. */
        if (ref_type_uses_access(r_type(rp))) {
            if (!r_has_attr(rp, a_execute) &&
                r_has_attr(rp, a_executable)
                ) {
                esp = esp_orig;
                return_error(e_invalidaccess);
            }
        }
        /* Executable nulls have a special meaning on the e-stack, */
        /* so since they are no-ops, don't push them. */
        if (!r_has_type_attrs(rp, t_null, a_executable)) {
            ++esp;
            ref_assign(esp, rp);
        }
    }
    esfile_check_cache();
    pop(n + 1);
    return o_push_estack;
}
示例#2
0
/*
 * Continuation for procedure data source.  We use the topmost aliasing slot
 * to remember whether we've just called the procedure (1) or whether we're
 * returning from a RemapColor callout (0).
 */
static int
image_proc_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_image_enum *penum = r_ptr(esp, gs_image_enum);
    int px = ETOP_PLANE_INDEX(esp)->value.intval;
    int num_sources = ETOP_NUM_SOURCES(esp)->value.intval;
    uint size, used[gs_image_max_planes];
    gs_const_string plane_data[gs_image_max_planes];
    const byte *wanted;
    int i, code;

    if (!r_has_type_attrs(op, t_string, a_read)) {
	check_op(1);
	/* Procedure didn't return a (readable) string.  Quit. */
	esp = zimage_pop_estack(esp);
	image_cleanup(i_ctx_p);
	return_error(!r_has_type(op, t_string) ? e_typecheck : e_invalidaccess);
    }
    size = r_size(op);
    if (size == 0 && ETOP_SOURCE(esp, 0)[1].value.intval == 0)
	code = 1;
    else {
	for (i = 0; i < num_sources; i++)
	    plane_data[i].size = 0;
	plane_data[px].data = op->value.bytes;
	plane_data[px].size = size;
	code = gs_image_next_planes(penum, plane_data, used);
	if (code == e_RemapColor) {
	    op->value.bytes += used[px]; /* skip used data */
	    r_dec_size(op, used[px]);
	    ETOP_SOURCE(esp, 0)[1].value.intval = 0; /* RemapColor callout */
	    return code;
	}
    }
    if (code) {			/* Stop now. */
	esp = zimage_pop_estack(esp);
	pop(1);
	image_cleanup(i_ctx_p);
	return (code < 0 ? code : o_pop_estack);
    }
    pop(1);
    wanted = gs_image_planes_wanted(penum);
    do {
	if (++px == num_sources)
	    px = 0;
    } while (!wanted[px]);
    ETOP_PLANE_INDEX(esp)->value.intval = px;
    return image_proc_process(i_ctx_p);
}
示例#3
0
/* r_size(op1) was set just above. */
static int
do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1)
{
    os_ptr op = osp;
    ref *arefs = op1->value.refs;
    uint asize = r_size(op1);
    uint i;
    ref *rq;

    /*
     * Copy elements from the stack to the array,
     * optionally skipping executable nulls.
     * Clear the executable bit in any internal operators, and
     * convert t_structs and t_astructs (which can only appear
     * in connection with stack marks, which means that they will
     * probably be freed when unwinding) to something harmless.
     */
    for (i = 0, rq = arefs + asize; rq != arefs; ++i) {
        const ref *rp = ref_stack_index(&e_stack, (long)i);

        if (r_has_type_attrs(rp, t_null, a_executable) && !include_marks)
            continue;
        --rq;
        ref_assign_old(op1, rq, rp, "execstack");
        switch (r_type(rq)) {
            case t_operator: {
                uint opidx = op_index(rq);

                if (opidx == 0 || op_def_is_internal(op_index_def(opidx)))
                    r_clear_attrs(rq, a_executable);
                break;
            }
            case t_struct:
            case t_astruct: {
                const char *tname = rq->value.pstruct ?
                    gs_struct_type_name_string(
                                gs_object_type(imemory, rq->value.pstruct))
                    : "NULL";

                make_const_string(rq, a_readonly | avm_foreign,
                                  strlen(tname), (const byte *)tname);
                break;
            }
            default:
                ;
        }
    }
    pop(op - op1);
    return 0;
}
示例#4
0
/*
 * Count the number of elements on the exec stack, with or without
 * the normally invisible elements (*op is a Boolean that indicates this).
 */
static uint
count_exec_stack(i_ctx_t *i_ctx_p, bool include_marks)
{
    uint count = ref_stack_count(&e_stack);

    if (!include_marks) {
        uint i;

        for (i = count; i--;)
            if (r_has_type_attrs(ref_stack_index(&e_stack, (long)i),
                                 t_null, a_executable))
                --count;
    }
    return count;
}
示例#5
0
/* Get the current file from which the interpreter is reading. */
static ref *
zget_current_file(i_ctx_t *i_ctx_p)
{
    ref_stack_enum_t rsenum;

    ref_stack_enum_begin(&rsenum, &e_stack);
    do {
        uint count = rsenum.size;
        es_ptr ep = rsenum.ptr + count - 1;

        for (; count; count--, ep--)
            if (r_has_type_attrs(ep, t_file, a_executable))
                return ep;
    } while (ref_stack_enum_next(&rsenum));
    return 0;
}
示例#6
0
/*
 * If a PostScript object is a Function procedure, return the function
 * object, otherwise return 0.
 */
gs_function_t *
ref_function(const ref *op)
{
    if (r_has_type(op, t_array) &&
        r_has_masked_attrs(op, a_executable | a_execute,
                           a_executable | a_all) &&
        r_size(op) == 2 &&
        r_has_type_attrs(op->value.refs + 1, t_operator, a_executable) &&
        op->value.refs[1].value.opproc == zexecfunction &&
        r_is_struct(op->value.refs) &&
        r_has_masked_attrs(op->value.refs, a_executable | a_execute,
                           a_executable | a_all)
        )
        return (gs_function_t *)op->value.refs->value.pstruct;
    return 0;
}
示例#7
0
/* <array> dictstack <subarray> */
static int
zdictstack(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint count = ref_stack_count(&d_stack);

    if (!level2_enabled)
	count--;		/* see dstack.h */
    if (!r_is_array(op))
	return_op_typecheck(op);
    if (r_size(op) < count)
        return_error(e_rangecheck);
    if (!r_has_type_attrs(op, t_array, a_write)) 
        return_error(e_invalidaccess);
    return ref_stack_store(&d_stack, op, count, 0, 0, true, idmemory,
			   "dictstack");
}
示例#8
0
/* <obj_0> ... <obj_n-1> <array> astore <array> */
static int
zastore(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint size;
    int code;

    if (!r_is_array(op))
        return_op_typecheck(op);
    size = r_size(op);
    /* Amazingly, the following is valid: 0 array noaccess astore */
    if (size == 0)
        return 0;
    if (!r_has_type_attrs(op, t_array, a_write))
        return_error(gs_error_invalidaccess);
    if (size > op - osbot) {
        /* The store operation might involve other stack segments. */
        ref arr;

        if (size >= ref_stack_count(&o_stack))
            return_error(gs_error_stackunderflow);
        arr = *op;
        code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
                               "astore");
        if (code < 0)
            return code;
        ref_stack_pop(&o_stack, size);
        *ref_stack_index(&o_stack, 0) = arr;
    } else {
        code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
        if (code < 0)
            return code;
        op[-(int)size] = *op;
        pop(size);
    }
    return 0;
}