Ejemplo n.º 1
0
/* <dict> begin - */
int
zbegin(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

    check_type(*op, t_dictionary);
    check_dict_read(*op);
    if ( dsp == dstop ) { 
        int code = ref_stack_extend(&d_stack, 1);

        if ( code < 0 ) {
            if (code == e_dictstackoverflow) {
                /* Adobe doesn't restore the operand that caused stack */
                /* overflow. We do the same to match CET 20-02-02      */
                pop(1);
            }
            return code;
        }
    }
    ++dsp;
    ref_assign(dsp, op);
    dict_set_top();
    pop(1);
    return 0;
}
Ejemplo n.º 2
0
/* - end - */
int
zend(i_ctx_t *i_ctx_p)
{
    if (ref_stack_count_inline(&d_stack) == min_dstack_size) {
	/* We would underflow the d-stack. */
	return_error(e_dictstackunderflow);
    }
    while (dsp == dsbot) {
	/* We would underflow the current block. */
	ref_stack_pop_block(&d_stack);
    }
    dsp--;
    dict_set_top();
    return 0;
}
Ejemplo n.º 3
0
/* or if the object did not have the access already when modify=1. */
static int
access_check(i_ctx_t *i_ctx_p,
	     int access,	/* mask for attrs */
	     bool modify)	/* if true, reduce access */
{
    os_ptr op = osp;
    ref *aop;

    switch (r_type(op)) {
	case t_dictionary:
	    aop = dict_access_ref(op);
	    if (modify) {
		if (!r_has_attrs(aop, access))
		    return_error(e_invalidaccess);
		ref_save(op, aop, "access_check(modify)");
		r_clear_attrs(aop, a_all);
		r_set_attrs(aop, access);
		dict_set_top();
		return 0;
	    }
	    break;
	case t_array:
	case t_file:
	case t_string:
	case t_mixedarray:
	case t_shortarray:
	case t_astruct:
	case t_device:;
	    if (modify) {
		if (!r_has_attrs(op, access))
		    return_error(e_invalidaccess);
		r_clear_attrs(op, a_all);
		r_set_attrs(op, access);
		return 0;
	    }
	    aop = op;
	    break;
	default:
	    return_op_typecheck(op);
    }
    return (r_has_attrs(aop, access) ? 1 : 0);
}
Ejemplo n.º 4
0
int
zrestore(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    alloc_save_t *asave;
    bool last;
    vm_save_t *vmsave;
    int code = restore_check_operand(op, &asave, idmemory);

    if (code < 0)
        return code;
    if_debug2('u', "[u]vmrestore 0x%lx, id = %lu\n",
              (ulong) alloc_save_client_data(asave),
              (ulong) op->value.saveid);
    if (I_VALIDATE_BEFORE_RESTORE)
        ivalidate_clean_spaces(i_ctx_p);
    /* Check the contents of the stacks. */
    osp--;
    {
        int code;

        if ((code = restore_check_stack(i_ctx_p, &o_stack, asave, false)) < 0 ||
                (code = restore_check_stack(i_ctx_p, &e_stack, asave, true)) < 0 ||
                (code = restore_check_stack(i_ctx_p, &d_stack, asave, false)) < 0
           ) {
            osp++;
            return code;
        }
    }
    /* Reset l_new in all stack entries if the new save level is zero. */
    /* Also do some special fixing on the e-stack. */
    restore_fix_stack(&o_stack, asave, false);
    restore_fix_stack(&e_stack, asave, true);
    restore_fix_stack(&d_stack, asave, false);
    /* Iteratively restore the state of memory, */
    /* also doing a grestoreall at each step. */
    do {
        vmsave = alloc_save_client_data(alloc_save_current(idmemory));
        /* Restore the graphics state. */
        gs_grestoreall_for_restore(igs, vmsave->gsave);
        /*
         * If alloc_save_space decided to do a second save, the vmsave
         * object was allocated one save level less deep than the
         * current level, so ifree_object won't actually free it;
         * however, it points to a gsave object that definitely
         * *has* been freed.  In order not to trip up the garbage
         * collector, we clear the gsave pointer now.
         */
        vmsave->gsave = 0;
        /* Now it's safe to restore the state of memory. */
        code = alloc_restore_step_in(idmemory, asave);
        if (code < 0)
            return code;
        last = code;
    }
    while (!last);
    {
        uint space = icurrent_space;

        ialloc_set_space(idmemory, avm_local);
        ifree_object(vmsave, "zrestore");
        ialloc_set_space(idmemory, space);
    }
    dict_set_top();		/* reload dict stack cache */
    if (I_VALIDATE_AFTER_RESTORE)
        ivalidate_clean_spaces(i_ctx_p);
    /* If the i_ctx_p LockFilePermissions is true, but the userparams */
    /* we just restored is false, we need to make sure that we do not */
    /* cause an 'invalidaccess' in setuserparams. Temporarily set     */
    /* LockFilePermissions false until the gs_lev2.ps can do a        */
    /* setuserparams from the restored userparam dictionary.          */
    i_ctx_p->LockFilePermissions = false;
    return 0;
}
Ejemplo n.º 5
0
static int
set_language_level(i_ctx_t *i_ctx_p, int new_level)
{
    int old_level = LANGUAGE_LEVEL;
    ref *pgdict =		/* globaldict, if present */
	ref_stack_index(&d_stack, ref_stack_count(&d_stack) - 2);
    ref *level2dict;
    int code = 0;

    if (new_level < 1 ||
	new_level >
	(dict_find_string(systemdict, "ll3dict", &level2dict) > 0 ? 3 : 2)
	)
	return_error(e_rangecheck);
    if (dict_find_string(systemdict, "level2dict", &level2dict) <= 0)
	return_error(e_undefined);
    /*
     * As noted in dstack.h, we allocate the extra d-stack entry for
     * globaldict even in Level 1 mode; in Level 1 mode, this entry
     * holds an extra copy of systemdict, and [count]dictstack omit the
     * very bottommost entry.
     */
    while (new_level != old_level) {
	switch (old_level) {
	    case 1: {		/* 1 => 2 or 3 */
				/* Put globaldict in the dictionary stack. */
		ref *pdict;

		/*
		 * This might be called so early in initialization that
		 * globaldict hasn't been defined yet.  If so, just skip
		 * this step.
		 */
		code = dict_find_string(level2dict, "globaldict", &pdict);
		if (code > 0) {
		    if (!r_has_type(pdict, t_dictionary))
			return_error(e_typecheck);
		    *pgdict = *pdict;
		}
		/* Set other flags for Level 2 operation. */
		imemory->gs_lib_ctx->dict_auto_expand = true;
		}
		code = swap_level_dict(i_ctx_p, "level2dict");
		if (code < 0)
		    return code;
		++old_level;
		continue;
	    case 3:		/* 3 => 1 or 2 */
		code = swap_level_dict(i_ctx_p, "ll3dict");
		if (code < 0)
		    return code;
		--old_level;
		continue;
	    default:		/* 2 => 1 or 3 */
		break;
	}
	switch (new_level) {
	    case 1: {		/* 2 => 1 */
		/*
		 * Clear the cached definition pointers of all names defined
		 * in globaldict.  This will slow down future lookups, but
		 * we don't care.
		 */
		int index = dict_first(pgdict);
		ref elt[2];

		while ((index = dict_next(pgdict, index, &elt[0])) >= 0)
		    if (r_has_type(&elt[0], t_name))
		        name_invalidate_value_cache(imemory, &elt[0]);
		/* Overwrite globaldict in the dictionary stack. */
		*pgdict = *systemdict;
		/* Set other flags for Level 1 operation. */
		imemory->gs_lib_ctx->dict_auto_expand = false;
		}
		code = swap_level_dict(i_ctx_p, "level2dict");
		break;
	    case 3:		/* 2 => 3 */
		code = swap_level_dict(i_ctx_p, "ll3dict");
		break;
	    default:		/* not possible */
		return_error(e_Fatal);
	}
	break;
    }
    dict_set_top();		/* reload dict stack cache */
    return code;
}