Переглянути джерело

fix: 修复权限管理机制

允许self形参.运算默认为pri访问权限
修复addVar的行为
SongZihuan 4 роки тому
батько
коміт
34cf12e50b

+ 4 - 4
vmcore/src/__run.c

@@ -361,7 +361,7 @@ LinkValue *findAttributes(wchar_t *name, bool free_old, fline line, char *file,
     LinkValue *attr;
     gc_freeze(inter, var_list, belong->value->object.var, true);
     attr = findStrVar(name, free_old, line, file, nowrun, CFUNC_NT(belong->value->object.var, result, belong));
-    if (attr != NULL && (attr->belong == NULL || attr->belong->value != belong->value && checkAttribution(belong->value, attr->belong->value)))
+    if (attr != NULL && (attr->belong == NULL || attr->belong->value == belong->value || checkAttribution(belong->value, attr->belong->value)))
         attr->belong = belong;
     gc_freeze(inter, var_list, belong->value->object.var, false);
     return attr;
@@ -522,12 +522,12 @@ bool is_indexException(LinkValue *value, Inter *inter) {
     return value->value == inter->data.base_exc[E_IndexException]->value || checkAttribution(value->value, inter->data.base_exc[E_IndexException]->value);
 }
 
-bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, char *file, char *name, bool pri_auto, FUNC_NT) {
+bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, char *file, wchar_t *name, bool pri_auto, FUNC_NT) {
     if ((value == public_aut || (!pri_auto && value == auto_aut)) && (base != public_aut && base != auto_aut)) {
         if (name == NULL)
             setResultError(E_PermissionsException, L"wrong Permissions: access variables as public", line, file, true, CNEXT_NT);
         else {
-            wchar_t *message = memWidecat(L"wrong Permissions: access variables as public: ", memStrToWcs(name, false), false, true);
+            wchar_t *message = memWidecat(L"wrong Permissions: access variables as public: ", name, false, false);
             setResultError(E_PermissionsException, message, line, file, true, CNEXT_NT);
             memFree(message);
         }
@@ -536,7 +536,7 @@ bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, c
         if (name == NULL)
             setResultError(E_PermissionsException, L"wrong Permissions: access variables as protect", line, file, true, CNEXT_NT);
         else {
-            wchar_t *message = memWidecat(L"wrong Permissions: access variables as protect: ", memStrToWcs(name, false), false, true);
+            wchar_t *message = memWidecat(L"wrong Permissions: access variables as protect: ", name, false, false);
             setResultError(E_PermissionsException, message, line, file, true, CNEXT_NT);
             memFree(message);
         }

+ 1 - 1
vmcore/src/include/__run.h

@@ -28,7 +28,7 @@ bool checkBool(LinkValue *value, fline line, char *file, FUNC_NT);
 wchar_t *getRepoStr(LinkValue *value, bool is_repo, fline line, char *file, FUNC_NT);
 bool is_iterStop(LinkValue *value, Inter *inter);
 bool is_indexException(LinkValue *value, Inter *inter);
-bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, char *file, char *name, bool pri_auto, FUNC_NT);
+bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, char *file, wchar_t *name, bool pri_auto, FUNC_NT);
 LinkValue *make_new(Inter *inter, LinkValue *belong, LinkValue *class);
 int run_init(LinkValue *obj, Argument *arg, fline line, char *file, FUNC_NT);
 bool setBoolAttrible(bool value, wchar_t *var, fline line, char *file, LinkValue *obj, FUNC_NT);

+ 1 - 2
vmcore/src/parameter.c

@@ -369,8 +369,7 @@ ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, vint
             }
             setResultErrorSt(E_ArgumentException, FEW_ARG, true, name, CNEXT_NT);
             goto return_;
-        }
-        else if (!checkAut(name->aut, value->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
+        } else if (!checkAut(name->aut, value->aut, name->line, name->code_file, NULL, false, CNEXT_NT))  // 与varAss作用相同
             goto return_;
 
         not_return:

+ 2 - 2
vmcore/src/run.c

@@ -111,8 +111,8 @@ ResultType runStatement(FUNC) {
             break;
     }
 
-    if (RUN_TYPE(type) && result->value->aut == auto_aut)
-        result->value->aut = st->aut;
+    if (RUN_TYPE(type) && st->aut != auto_aut)
+        result->value->aut = st->aut;  // 权限覆盖
     result->node = st;
 #if START_GC
     gc_freeTmpLink(&belong->gc_status);

+ 8 - 8
vmcore/src/runcall.c

@@ -218,23 +218,23 @@ static ResultType callObject(LinkValue *object_value, Argument *arg, fline line,
     return result->type;
 }
 
-static ResultType callCFunction(LinkValue *function_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT){
+static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT){
     VarList *function_var = NULL;
     OfficialFunction of = NULL;
     Argument *bak;
     setResultCore(result);
-    gc_addTmpLink(&function_value->gc_status);
+    gc_addTmpLink(&func_value->gc_status);
 
-    setFunctionArgument(&arg, &bak, function_value, line, file, pt_sep, CNEXT_NT);
+    setFunctionArgument(&arg, &bak, func_value, line, file, pt_sep, CNEXT_NT);
     if (!CHECK_RESULT(result))
         goto return_;
 
-    of = function_value->value->data.function.of;
-    function_var = pushVarList(function_value->value->object.out_var != NULL ? function_value->value->object.out_var : var_list, inter);
+    of = func_value->value->data.function.of;
+    function_var = pushVarList(func_value->value->object.out_var != NULL ? func_value->value->object.out_var : var_list, inter);
     gc_freeze(inter, var_list, function_var, true);
 
     freeResult(result);
-    of(CO_FUNC(arg, function_var, result, function_value));
+    of(CO_FUNC(arg, function_var, result, func_value->belong));  // belong设置为func的belong, 方便权限的认定
     if (result->type == R_func)
         result->type = R_opt;
     else if (result->type != R_opt && result->type != R_error)
@@ -244,7 +244,7 @@ static ResultType callCFunction(LinkValue *function_value, Argument *arg, long i
     popVarList(function_var);
     freeFunctionArgument(arg, bak);
 
-    return_: gc_freeTmpLink(&function_value->gc_status);
+    return_: gc_freeTmpLink(&func_value->gc_status);
     return result->type;
 }
 
@@ -530,7 +530,7 @@ static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int
         goto return_;
 
     freeResult(result);
-    functionSafeInterStatement(CFUNC(st_func, var_func, result, func_value));  // 运行函数的时候, belong调整为函数本身
+    functionSafeInterStatement(CFUNC(st_func, var_func, result, func_value->belong));  // belong设置为函数的belong,方便权限校对
 
     return_:
     gc_freeze(inter, var_list, var_func, false);

+ 26 - 30
vmcore/src/runoperation.c

@@ -119,7 +119,7 @@ ResultType blockOperation(FUNC) {
     else
         setBlockResult(st, yield_run, result, CFUNC_CORE(var_list));
     if (CHECK_RESULT(result) && st->aut != auto_aut)
-        result->value->aut = st->aut;
+        result->value->aut = st->aut;  // 权限覆盖
     return result->type;
 }
 
@@ -173,10 +173,13 @@ ResultType boolOperation(FUNC) {
 ResultType pointOperation(FUNC) {
     LinkValue *left;
     VarList *object = NULL;
+    bool pri_auto;
     setResultCore(result);
     if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)) || result->value->value->type == V_none)
         return result->type;
     GET_RESULT(left, result);
+    if (st->aut != auto_aut)
+        left->aut = st->aut;  // 权限覆盖
 
     if (st->u.operation.OperationType == OPT_POINT)
         object = left->value->object.var;
@@ -184,15 +187,15 @@ ResultType pointOperation(FUNC) {
         object = left->value->object.out_var;
 
     if (object == NULL) {
-        setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), st->line, st->code_file, true,
-                       CNEXT_NT);
+        setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), st->line, st->code_file, true, CNEXT_NT);
         goto return_;
     }
     gc_freeze(inter, var_list, object, true);
     operationSafeInterStatement(CFUNC(st->u.operation.right, object, result, left));  // 点运算运算时需要调整belong为点的左值
-    if (!CHECK_RESULT(result) || !checkAut(left->aut, result->value->aut, st->line, st->code_file, NULL, false, CNEXT_NT))
+    pri_auto = result->value->belong == NULL || result->value->belong->value == belong->value || checkAttribution(belong->value, result->value->belong->value);
+    if (!CHECK_RESULT(result) || !checkAut(left->aut, result->value->aut, st->line, st->code_file, NULL, pri_auto, CNEXT_NT))
         PASS;
-    else if (result->value->belong == NULL || result->value->belong->value != left->value && checkAttribution(left->value, result->value->belong->value))
+    else if (result->value->belong == NULL || result->value->belong->value == left->value || checkAttribution(left->value, result->value->belong->value))  // 检查result所属于的对象是否位左值的父亲
         result->value->belong = left;
     gc_freeze(inter, var_list, object, false);
 
@@ -244,9 +247,8 @@ ResultType varDel(Statement *name, bool check_aut, FUNC_NT) {
     if (check_aut) {
         LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CFUNC_CORE(var_list));
         freeResult(result);
-        if (tmp != NULL && !checkAut(name->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT)) {
+        if (tmp != NULL && !checkAut(name->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
             goto return_;
-        }
     }
     findFromVarList(str_name, int_times, del_var, CFUNC_CORE(var_list));
     setResult(result, inter);
@@ -256,21 +258,18 @@ ResultType varDel(Statement *name, bool check_aut, FUNC_NT) {
 }
 
 ResultType pointDel(Statement *name, FUNC_NT) {
-    Result left;
+    LinkValue *left;
     VarList *object = NULL;
     Statement *right = name->u.operation.right;
 
     setResultCore(result);
     if (operationSafeInterStatement(CFUNC(name->u.operation.left, var_list, result, belong)))
         return result->type;
-    left = *result;
-    setResultCore(result);
-
-    object = name->u.operation.OperationType == OPT_POINT ? left.value->value->object.var : left.value->value->object.out_var;
+    GET_RESULT(left, result);  // 不关心左值和整体(st)权限
 
+    object = name->u.operation.OperationType == OPT_POINT ? left->value->object.var : left->value->object.out_var;
     if (object == NULL) {
-        setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), name->line, name->code_file, true,
-                       CNEXT_NT);
+        setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), name->line, name->code_file, true, CNEXT_NT);
         goto return_;
     }
 
@@ -282,7 +281,7 @@ ResultType pointDel(Statement *name, FUNC_NT) {
     gc_freeze(inter, var_list, object, false);
 
     return_:
-    freeResult(&left);
+    gc_freeTmpLink(&left->gc_status);
     return result->type;
 }
 
@@ -311,8 +310,7 @@ ResultType downDel(Statement *name, FUNC_NT) {
         if (!CHECK_RESULT(result))
             goto dderror_;
         freeResult(result);
-        callBackCore(_func_, arg, name->line, name->code_file, 0,
-                     CNEXT_NT);
+        callBackCore(_func_, arg, name->line, name->code_file, 0, CNEXT_NT);
 
         dderror_:
         gc_freeTmpLink(&_func_->gc_status);
@@ -383,15 +381,14 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool settin
         return result->type;
     }
     GET_RESULT(name_, result);
-    if (name->aut != auto_aut)
+    if (name->aut != auto_aut)  // 当左值设定访问权限的时候, 覆盖右值的权限
         value->aut = name->aut;
 
     tmp = findFromVarList(str_name, int_times, read_var, CFUNC_CORE(var_list));
     if (check_aut) {
         if (tmp != NULL && !checkAut(value->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
             goto error_;
-    } else if (name->aut != auto_aut && tmp != NULL)
-        tmp->aut = value->aut;
+    }
 
     if (tmp == NULL || !run || !setVarFunc(tmp, value, name->line, name->code_file, CNEXT_NT))
         addFromVarList(str_name, name_, int_times, value, CFUNC_CORE(var_list));
@@ -479,21 +476,18 @@ ResultType downAss(Statement *name, LinkValue *value, FUNC_NT) {
 }
 
 ResultType pointAss(Statement *name, LinkValue *value, FUNC_NT) {
-    Result left;
+    LinkValue *left;
     Statement *right = name->u.operation.right;
     VarList *object = NULL;
 
     setResultCore(result);
     if (operationSafeInterStatement(CFUNC(name->u.operation.left, var_list, result, belong)))
         return result->type;
-    left = *result;
-    setResultCore(result);
-
-    object = name->u.operation.OperationType == OPT_POINT ? left.value->value->object.var : left.value->value->object.out_var;
+    GET_RESULT(left, result);  // 不关心左值和整体(st)权限
 
+    object = name->u.operation.OperationType == OPT_POINT ? left->value->object.var : left->value->object.out_var;
     if (object == NULL) {
-        setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), name->line, name->code_file, true,
-                       CNEXT_NT);
+        setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), name->line, name->code_file, true, CNEXT_NT);
         goto return_;
     }
 
@@ -505,7 +499,7 @@ ResultType pointAss(Statement *name, LinkValue *value, FUNC_NT) {
     gc_freeze(inter, var_list, object, false);
 
     return_:
-    freeResult(&left);
+    gc_freeTmpLink(&left->gc_status);
     return result->type;
 }
 
@@ -569,7 +563,7 @@ ResultType getVar(FUNC, VarInfo var_info) {
             setResultOperationBase(result, val);
         } else
             setNameException(val, name, st->line, st->code_file, CNEXT_NT);
-    } else if (checkAut(st->aut, var->aut, st->line, st->code_file, NULL, true, CNEXT_NT)) {
+    } else if (checkAut(st->aut, var->aut, st->line, st->code_file, name, true, CNEXT_NT)) {  // 默认访问权限为pri
         bool run = st->type == base_var ? st->u.base_var.run : st->type == base_svar ? st->u.base_svar.run : false;
         if (!run || !runVarFunc(var, st->line, st->code_file, CNEXT_NT))
             setResultOperationBase(result, var);
@@ -587,7 +581,7 @@ ResultType getBaseValue(FUNC) {
         result->type = R_opt;
         gc_addTmpLink(&result->value->gc_status);
     }
-    else
+    else {
         switch (st->u.base_value.type) {
             case number_str: {
                 if (wcschr(st->u.base_value.str, '.') == NULL)
@@ -612,6 +606,8 @@ ResultType getBaseValue(FUNC) {
                 makeStringValue(st->u.base_value.str, st->line, st->code_file, CNEXT_NT);
                 break;
         }
+        result->value->belong = belong;
+    }
     return result->type;
 }
 

+ 2 - 1
vmcore/src/value.c

@@ -67,6 +67,7 @@ Value *makeIntValue(vint num, fline line, char *file, FUNC_NT) {
     callBackCore(inter->data.base_obj[B_INT_], NULL, line, file, 0, CNEXT_NT);
     if (!CHECK_RESULT(result))
         return NULL;
+    result->value->belong = belong;
     tmp = result->value->value;
     tmp->data.int_.num = num;
     return tmp;
@@ -619,7 +620,7 @@ bool callDel(Value *object_value, Result *result, Inter *inter, VarList *var_lis
 
     if (_del_ != NULL){
         gc_addTmpLink(&_del_->gc_status);
-        if (_del_->belong == NULL || _del_->belong->value != object_value && checkAttribution(object_value, _del_->belong->value))
+        if (_del_->belong == NULL || _del_->belong->value == object_value || checkAttribution(object_value, _del_->belong->value))
             _del_->belong = makeLinkValue(object_value, inter->base_belong, inter);
         callBackCore(_del_, NULL, LINEFILE, 0, CFUNC_NT(var_list, result, inter->base_belong));
         gc_freeTmpLink(&_del_->gc_status);

+ 15 - 2
vmcore/src/var.c

@@ -155,8 +155,21 @@ static void addVarCore(Var **base, wchar_t *name, LinkValue *value, LinkValue *n
             *base = makeVar(name, value, name_, inter);
             break;
         } else if (eqWide((*base)->name, name)) {
-            (*base)->value->value = value->value;
-            (*base)->value->belong = value->belong;
+            enum ValueAuthority aut = (*base)->value->aut;
+            (*base)->value = copyLinkValue(value, inter);
+            switch (aut) {
+                default:
+                case public_aut:
+                case auto_aut:
+                    break;
+                case protect_aut:
+                    if (value->aut != private_aut)
+                        (*base)->value->aut = protect_aut;
+                    break;
+                case private_aut:
+                    (*base)->value->aut = private_aut;
+                    break;
+            }
             break;
         }
     }