summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--hieroglyph/operator.c12
-rw-r--r--hieroglyph/version.h.in2
-rw-r--r--hieroglyph/vm.c49
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 <at@gclab.org>
+ * 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;
@@ -138,6 +139,29 @@ static HgObjectVTable __hg_vm_vtable = {
};
/*
+ * 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
*/
static void
@@ -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;
}