/* 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); }
/* (presumably systemdict). */ static int dict_find_password(ref ** ppvalue, const ref * pdref, const char *kstr) { ref *pvalue; if (dict_find_string(pdref, kstr, &pvalue) <= 0) return_error(e_undefined); if (!r_has_type(pvalue, t_string) || r_has_attrs(pvalue, a_read) || pvalue->value.const_bytes[0] >= r_size(pvalue) ) return_error(e_rangecheck); *ppvalue = pvalue; return 0; }
/* <obj:array|packedarray|dict|file|string> noaccess <obj> */ static int znoaccess(i_ctx_t *i_ctx_p) { os_ptr op = osp; check_op(1); if (r_has_type(op, t_dictionary)) { ref *aop = dict_access_ref(op); /* CPSI throws invalidaccess when seting noaccess to a readonly dictionary (CET 13-13-6) : */ if (!r_has_attrs(aop, a_write)) { if (!r_has_attrs(aop, a_read) && !r_has_attrs(aop, a_execute)) { /* Already noaccess - do nothing (CET 24-09-1). */ return 0; } return_error(e_invalidaccess); } /* Don't allow removing read access to permanent dictionaries. */ if (dict_is_permanent_on_dstack(op)) return_error(e_invalidaccess); } return access_check(i_ctx_p, 0, true); }