Ver Fonte

feat: 变量权限管理添加对写入权限和变量定义的支持

修改变量的值需经权限验证
定义新变量需检查变量空间属主
SongZihuan há 3 anos atrás
pai
commit
ca960a1354
7 ficheiros alterados com 104 adições e 28 exclusões
  1. 1 1
      include/object.h
  2. 10 5
      include/var.h
  3. 7 4
      src/core/env.c
  4. 2 1
      src/core/func.c
  5. 2 2
      src/core/object.c
  6. 79 12
      src/core/var.c
  7. 3 3
      src/main.c

+ 1 - 1
include/object.h

@@ -25,7 +25,7 @@ af_Object *findObjectAttributes(char *name, af_Object *visitor, af_Object *obj);
 
 /* 对象属性设置 */
 bool setObjectAttributes(char *name, char p_self, char p_posterity, char p_external, af_Object *attributes,
-                         af_Object *obj, af_Environment *env);
+                         af_Object *obj, af_Object *visitor, af_Environment *env);
 
 /* 对象继承关系函数 */
 af_Inherit *makeInherit(af_Object *obj);

+ 10 - 5
include/var.h

@@ -19,17 +19,22 @@ void addVarNode(af_Var var, af_Object *obj, char *id);
 af_VarSpace *makeVarSpace(af_Object *belong, af_Environment *env);
 void freeVarSpace(af_VarSpace *vs, af_Environment *env);
 
-/* 变量赋值类函数 */
-bool addVarToVarSpace(af_Var *var, af_VarSpace *vs);
+/* 变量定义类函数 */
+bool addVarToVarSpace(af_Var *var, af_Object *visitor, af_VarSpace *vs);
 bool makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_VarSpace *vs,
-                       af_Environment *env);
-bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl);
+                       af_Object *visitor, af_Environment *env);
+bool addVarToVarSpaceList(af_Var *var, af_Object *visitor, af_VarSpaceListNode *vsl);
 bool makeVarToVarSpaceList(char *name, char p_self, char p_posterity, char p_external, af_Object *obj,
-                           af_VarSpaceListNode *vsl, af_Environment *env);
+                           af_VarSpaceListNode *vsl, af_Object *visitor, af_Environment *env);
 
 /* 变量寻值类函数 */
 af_Var *findVarFromVarSpace(char *name, af_Object *visitor, af_VarSpace *vs);
 af_Var *findVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *vsl);
+
+/* 变量设置类函数 */
+bool setVarToVarSpace(char *name, af_Object *obj, af_Object *visitor, af_VarSpace *vs);
+bool setVarToVarList(char *name, af_Object *obj, af_Object *visitor, af_VarSpaceListNode *vsl);
+
 /* 变量空间链的创建与释放 */
 af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs);
 af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl);

+ 7 - 4
src/core/env.c

@@ -458,7 +458,7 @@ void freeEnvironment(af_Environment *env) {
 }
 
 bool addVarToProtectVarSpace(af_Var *var, af_Environment *env) {
-    return addVarToVarSpace(var, env->core->protect);
+    return addVarToVarSpace(var, NULL, env->core->protect);
 }
 
 static af_TopMsgProcess *makeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func) {
@@ -775,21 +775,24 @@ bool setFuncActivityAddVar(af_Environment *env){
     }
 
     if (env->activity->fi->embedded != super_embedded) {  // 不是超内嵌函数则引入一层新的变量空间
-        env->activity->var_list = pushNewVarList(env->activity->func, env->activity->var_list, env);
+        /* 新层的变量空间应该属于belong而不是func */
+        env->activity->var_list = pushNewVarList(env->activity->belong, env->activity->var_list, env);
         env->activity->new_vs_count++;
     }
 
     env->activity->func_var_list = NULL;
 
     if (env->activity->fi->var_this && env->activity->belong != NULL) {
-        if (!makeVarToVarSpaceList("this", 3, 3, 3, env->activity->belong, env->activity->var_list, env)) {
+        if (!makeVarToVarSpaceList("this", 3, 3, 3, env->activity->belong,
+                                   env->activity->var_list, env->activity->belong, env)) {
             pushMessageDown(makeMessage("ERROR-STR", 0), env);
             return false;
         }
     }
 
     if (env->activity->fi->var_func && env->activity->func != NULL) {
-        if (!makeVarToVarSpaceList("func", 3, 3, 3, env->activity->func, env->activity->var_list, env)) {
+        if (!makeVarToVarSpaceList("func", 3, 3, 3, env->activity->func,
+                                   env->activity->var_list, env->activity->belong, env)) {
             pushMessageDown(makeMessage("ERROR-STR", 0), env);
             return false;
         }

+ 2 - 1
src/core/func.c

@@ -101,7 +101,8 @@ af_ArgList **pushNewArgList(af_ArgList **base, char *name, af_Object *obj) {
 
 bool runArgList(af_ArgList *al, af_VarSpaceListNode *vsl, af_Environment *env){
     for (NULL; al != NULL; al = al->next) {
-        if (!makeVarToVarSpaceList(al->name, 3, 3, 3, al->obj, vsl, env))
+        if (!makeVarToVarSpaceList(al->name, 3, 3, 3, al->obj, vsl,
+                                   env->activity->belong, env))
             return false;
     }
     return true;

+ 2 - 2
src/core/object.c

@@ -299,8 +299,8 @@ af_Object *findObjectAttributes(char *name, af_Object *visitor, af_Object *obj)
 }
 
 bool setObjectAttributes(char *name, char p_self, char p_posterity, char p_external, af_Object *attributes,
-                         af_Object *obj, af_Environment *env){
-    return makeVarToVarSpace(name, p_self, p_posterity, p_external, attributes, obj->data->var_space, env);
+                         af_Object *obj, af_Object *visitor, af_Environment *env){
+    return makeVarToVarSpace(name, p_self, p_posterity, p_external, attributes, obj->data->var_space, visitor, env);
 }
 
 af_Object *findObjectAttributesByObjectData(char *name, af_Object *visitor, af_ObjectData *od) {

+ 79 - 12
src/core/var.c

@@ -14,7 +14,10 @@ static void freeAllVarCup(af_VarCup *vp);
 
 /* VarSpace 寻值函数 */
 static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs);
+
+/* 变量权限函数 */
 static bool checkReadPermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs);
+static bool checkWritePermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs);
 
 static af_VarNode *makeVarNode(af_Object *obj, char *id) {
     af_VarNode *vn = calloc(sizeof(af_VarNode), 1);
@@ -166,16 +169,19 @@ bool freeVarSpaceListCount(size_t count, af_VarSpaceListNode *vsl) {
 /*
  * 函数名: addVarToVarSpace
  * 目标: 把var添加到VarSpace中
- * 若已存在同名Var则返回false不作修改
+ * 若空间被保护, 权限错误或已存在同名Var则返回false不作修改
  * 否则返回true
  */
-bool addVarToVarSpace(af_Var *var, af_VarSpace *vs) {
+bool addVarToVarSpace(af_Var *var, af_Object *visitor, af_VarSpace *vs) {
     time33_t index = time33(var->name) % VAR_HASHTABLE_SIZE;
     af_VarCup **pCup = &vs->var[index];
 
     if (vs->is_protect)
         return false;
 
+    if (vs->belong != NULL && (visitor == NULL || visitor->data != vs->belong->data))
+        return false;
+
     for (NULL; *pCup != NULL; pCup = &((*pCup)->next)) {
         if (EQ_STR((*pCup)->var->name, var->name))
             return false;
@@ -190,23 +196,36 @@ bool addVarToVarSpace(af_Var *var, af_VarSpace *vs) {
  * 目标: 创建一个新的var添加到VarSpace中
  * 若已存在同名Var则返回false不作修改
  * 否则返回true
+ * 调用 addVarToVarSpace
  */
 bool makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_VarSpace *vs,
-                       af_Environment *env){
-    return addVarToVarSpace(makeVar(name, p_self, p_posterity, p_external, obj, env), vs);
+                       af_Object *visitor, af_Environment *env){
+    return addVarToVarSpace(makeVar(name, p_self, p_posterity, p_external, obj, env), visitor, vs);
 }
 
-bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl) {
+/*
+ * 函数名: makeVarToVarSpace
+ * 目标: 添加一个Var到VarSpaceList
+ * 自动跳过保护空间
+ * 调用 addVarToVarSpace
+ */
+bool addVarToVarSpaceList(af_Var *var, af_Object *visitor, af_VarSpaceListNode *vsl) {
     for (NULL; vsl != NULL; vsl = vsl->next) {
         if (!vsl->vs->is_protect)
-            return addVarToVarSpace(var, vsl->vs);
+            return addVarToVarSpace(var, visitor, vsl->vs);
     }
     return false;
 }
 
+/*
+ * 函数名: makeVarToVarSpace
+ * 目标: 创建一个新的var到VarSpaceList
+ * 自动跳过保护空间
+ * 调用 addVarToVarSpaceList -> addVarToVarSpace
+ */
 bool makeVarToVarSpaceList(char *name, char p_self, char p_posterity, char p_external, af_Object *obj,
-                           af_VarSpaceListNode *vsl, af_Environment *env){
-    return addVarToVarSpaceList(makeVar(name, p_self, p_posterity, p_external, obj, env), vsl);
+                           af_VarSpaceListNode *vsl, af_Object *visitor, af_Environment *env){
+    return addVarToVarSpaceList(makeVar(name, p_self, p_posterity, p_external, obj, env), visitor, vsl);
 }
 
 /*
@@ -245,8 +264,7 @@ af_Var *findVarFromVarSpace(char *name, af_Object *visitor, af_VarSpace *vs){
 
     if (checkReadPermissions(var, visitor, vs))
         return var;
-    else
-        return NULL;
+    return NULL;
 }
 
 /*
@@ -263,14 +281,63 @@ af_Var *findVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *
         if (var != NULL) {
             if (checkReadPermissions(var, visitor, vsl->vs))
                 return var;
-            else
-                return NULL;
+            return NULL;
         }
     }
 
     return NULL;
 }
 
+static bool checkWritePermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs){
+    char p = var->permissions[2];  // 默认外部权限
+
+    if (vs->belong == NULL || (visitor != NULL && vs->belong->data == visitor->data))  // (无权限设定或ObjectData匹配) 应用自身权限
+        p = var->permissions[0];
+    else if (visitor != NULL && checkPosterity(vs->belong, visitor))  // 应用后代权限
+        p = var->permissions[1];
+
+    return p == 2 || p == 3;
+}
+
+/*
+ * 函数名: setVarToVarSpace
+ * 目标: 在VarSpace中搜索var并修改其值
+ * 调用: findVarFromVarSpaceByIndex
+ */
+bool setVarToVarSpace(char *name, af_Object *obj, af_Object *visitor, af_VarSpace *vs){
+    af_Var *var = findVarFromVarSpaceByIndex(time33(name) % VAR_HASHTABLE_SIZE, name, vs);
+    if (var == NULL)
+        return false;
+
+    if (checkWritePermissions(var, visitor, vs)) {
+        var->vn->obj = obj;
+        return true;
+    }
+    return false;
+}
+
+/*
+ * 函数名: setVarToVarList
+ * 目标: 在VarSpaceListNode中搜索var并修改其值
+ * 调用: findVarFromVarSpaceByIndex
+ */
+bool setVarToVarList(char *name, af_Object *obj, af_Object *visitor, af_VarSpaceListNode *vsl) {
+    time33_t index = time33(name) % VAR_HASHTABLE_SIZE;
+    af_Var *var = NULL;
+
+    for (NULL; vsl != NULL; vsl = vsl->next) {
+        var = findVarFromVarSpaceByIndex(index, name, vsl->vs);
+        if (var != NULL) {
+            if (checkWritePermissions(var, visitor, vsl->vs)) {
+                var->vn->obj = obj;
+                return true;
+            }
+            return false;
+        }
+    }
+    return false;
+}
+
 af_VarSpaceListNode *pushNewVarList(af_Object *belong, af_VarSpaceListNode *base, af_Environment *env){
     af_VarSpaceListNode *new = makeVarSpaceList(makeVarSpace(belong, env));
     new->next = base;

+ 3 - 3
src/main.c

@@ -294,7 +294,7 @@ af_FuncBody *testFunc6(int *mark, af_Environment *env) {  // 测试用函数
         FREE_SYMBOL(freeData_2);
     }
 
-    setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, env);
+    setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, obj, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc6[des](%p, %p): I am testFunc6\n", obj, des);
     return NULL;
@@ -346,7 +346,7 @@ af_FuncBody *testFunc5(int *mark, af_Environment *env) {  // 测试用函数
         FREE_SYMBOL(freeData_2);
     }
 
-    setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, env);
+    setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, obj, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc5(%p, %p): I am testFunc5\n", obj, des);
     return NULL;
@@ -694,7 +694,7 @@ int main() {
             FREE_SYMBOL(freeData_2);
         }
 
-        setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, env);
+        setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, obj, env);
         addVarToProtectVarSpace(makeVar("func6", 3, 3, 3, obj, env), env);
         printf("func6(%p)\n", obj);
     }