From 4ba655a460b68353de0437989c6d041b76cccdb7 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Tue, 17 Oct 2006 19:17:05 +0000 Subject: * hieroglyph/operator.c (_hg_operator_op_exec): save the current security level and rollback it after finished the object's execution. * hieroglyph/vm.c (_hg_vm_op_rollbacksecuritylevel): new function. (hg_vm_set_security_level): implemented. (hg_vm_get_security_level): implemented. --- ChangeLog | 7 +++++++ hieroglyph/operator.c | 12 ++++++++++-- hieroglyph/version.h.in | 2 +- hieroglyph/vm.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61fd039..364d283 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2006-10-18 Akira TAGOH + * hieroglyph/operator.c (_hg_operator_op_exec): save the current + security level and rollback it after finished the object's execution. + + * hieroglyph/vm.c (_hg_vm_op_rollbacksecuritylevel): new function. + (hg_vm_set_security_level): implemented. + (hg_vm_get_security_level): implemented. + * hieroglyph/operator.c (_hg_operator_op_countdictstack): check VMerror. (_hg_operator_op_countexecstack): likewise. diff --git a/hieroglyph/operator.c b/hieroglyph/operator.c index 8386eb7..4219ec0 100644 --- a/hieroglyph/operator.c +++ b/hieroglyph/operator.c @@ -2700,7 +2700,7 @@ G_STMT_START HgStack *ostack = hg_vm_get_ostack(vm); HgStack *estack = hg_vm_get_estack(vm); guint depth = hg_stack_depth(ostack); - HgValueNode *node, *self, *tmp; + HgValueNode *node, *self, *tmp, *slnode, *scnode; while (1) { if (depth < 1) { @@ -2715,11 +2715,19 @@ G_STMT_START break; } self = hg_stack_pop(estack); + /* save the current security level */ + HG_VALUE_MAKE_INTEGER (hg_vm_get_current_pool(vm), + slnode, + hg_vm_get_security_level(vm)); + hg_stack_push(estack, slnode); + scnode = hg_dict_lookup_with_string(hg_vm_get_dict_systemdict(vm), + "%rollback_securitylevel"); + hg_stack_push(estack, scnode); tmp = hg_object_copy((HgObject *)node); if (tmp) hg_stack_push(estack, tmp); retval = hg_stack_push(estack, self); - if (!tmp) + if (!tmp || !slnode) _hg_operator_set_error(vm, op, VM_e_VMerror); else if (!retval) _hg_operator_set_error(vm, op, VM_e_execstackoverflow); diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in index 5178be2..9de1d04 100644 --- a/hieroglyph/version.h.in +++ b/hieroglyph/version.h.in @@ -29,7 +29,7 @@ G_BEGIN_DECLS #define HIEROGLYPH_VERSION "@VERSION@" -#define HIEROGLYPH_UUID "9d305066-1908-42bc-b40a-451a78961c83" +#define HIEROGLYPH_UUID "80a3394e-e1f2-44be-a70c-2128bd4f108d" const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$"; diff --git a/hieroglyph/vm.c b/hieroglyph/vm.c index 891234b..cf2393f 100644 --- a/hieroglyph/vm.c +++ b/hieroglyph/vm.c @@ -74,6 +74,7 @@ struct _HieroGlyphVirtualMachine { GRand *random_generator; gint32 error_code; gboolean shutdown; + gint32 security_level; /* job management */ GList *saved_jobs; @@ -137,6 +138,29 @@ static HgObjectVTable __hg_vm_vtable = { .to_string = NULL, }; +/* + * special operators + */ +static gboolean +_hg_vm_op_rollbacksecuritylevel(HgOperator *op, + gpointer data) +{ + HgVM *vm = data; + gboolean retval = FALSE; + HgStack *estack = hg_vm_get_estack(vm); + HgValueNode *nself, *node; + + nself = hg_stack_index(estack, 0); + node = hg_stack_index(estack, 1); + vm->security_level = HG_VALUE_GET_INTEGER (node); + hg_stack_pop(estack); + hg_stack_pop(estack); + retval = hg_stack_push(estack, nself); /* dummy */ + /* it must be true */ + + return retval; +} + /* * Private Functions */ @@ -999,6 +1023,18 @@ hg_vm_startjob(HgVM *vm, if (!hg_operator_init(vm)) return FALSE; + /* initialize the special operators */ +#define BUILD_OP(_vm_, _pool_, _sdict_, _name_, _func_) \ + G_STMT_START { \ + HgOperator *__hg_op; \ + \ + hg_operator_build_operator__inline(_hg_vm_op_, (_vm_), (_pool_), (_sdict_), _name_, _func_, __hg_op); \ + } G_STMT_END + + BUILD_OP (vm, vm->global_pool, vm->systemdict, %rollback_securitylevel, rollbacksecuritylevel); + +#undef BUILD_OP + /* FIXME: initialize graphics */ hg_vm_use_global_pool(vm, FALSE); @@ -1565,12 +1601,21 @@ hg_vm_shutdown(HgVM *vm, gint32 hg_vm_get_security_level(HgVM *vm) { - return 0; + g_return_val_if_fail(vm != NULL, G_MAXINT32); + + return vm->security_level; } gboolean hg_vm_set_security_level(HgVM *vm, gint32 level) { - return FALSE; + g_return_val_if_fail (vm != NULL, FALSE); + + if (hg_vm_get_security_level(vm) > level) + return FALSE; + + vm->security_level = level; + + return TRUE; } -- cgit v1.2.3