diff --git a/src/cm_common/cm_misc_res.cpp b/src/cm_common/cm_misc_res.cpp index 0167903..3b8c064 100644 --- a/src/cm_common/cm_misc_res.cpp +++ b/src/cm_common/cm_misc_res.cpp @@ -169,6 +169,17 @@ bool IsResConfValid(const char *param, int value) return false; } +bool IsKeyInRestrictList(const char *key) +{ + uint32 arrLen = (sizeof(g_resConfRange) / sizeof(g_resConfRange[0])); + for (uint32 i = 0; i < arrLen; ++i) { + if (strcmp(key, g_resConfRange[i].param) == 0) { + return true; + } + } + return false; +} + int ResConfMaxValue(const char *param) { uint32 arrLen = (sizeof(g_resConfRange) / sizeof(g_resConfRange[0])); diff --git a/src/cm_ctl/ctl_res.cpp b/src/cm_ctl/ctl_res.cpp index deb4748..df74abe 100644 --- a/src/cm_ctl/ctl_res.cpp +++ b/src/cm_ctl/ctl_res.cpp @@ -37,6 +37,8 @@ #include "ctl_res_list.h" static char g_jsonFile[CM_PATH_LENGTH] = {0}; +static char g_resNames[CM_MAX_RES_COUNT + CM_MAX_VIP_COUNT][CM_MAX_RES_NAME]; +static uint32 g_resCount = 0; // res static const char *g_resSkipMap[] = {RES_NAME, RESOURCE_TYPE, INSTANCES}; @@ -328,7 +330,12 @@ status_t ProcessResAttrConfJson( { CM_RETURN_IFERR(AddItemToObject(resCtx, confObj, key, value, RES_LEVEL_RES)); uint32 index; - if (cm_str_equal(key, RESOURCE_TYPE) && CompareResType(value, &index)) { + if (cm_str_equal(key, RESOURCE_TYPE)) { + if (!CompareResType(value, &index)) { + write_runlog(ERROR, "%s%s Res(%s) attr %s can not be set to %s.\n", GetResOperStr(resCtx->mode), + GetInstOperStr(resCtx->inst.mode), resCtx->resName, RESOURCE_TYPE, value); + return CM_ERROR; + } if (GetResTypeValue(index) == NULL) { return CM_SUCCESS; } @@ -505,21 +512,34 @@ cJSON *GetCurResInArray(cJSON *resArray, const char *resName, const ResOption *r } cJSON *resObj; - char *curResName; + const uint32 maxResCnt = CM_MAX_RES_COUNT + CM_MAX_VIP_COUNT; + //char resName[maxResCnt][CM_MAX_RES_NAME]; + g_resCount = 0; + int32 resIndex = -1; int32 arraySize = cJSON_GetArraySize(resArray); for (int32 i = 0; i < arraySize; ++i) { resObj = cJSON_GetArrayItem(resArray, i); if (!cJSON_IsObject(resObj)) { continue; } - curResName = GetValueStrFromCJson(resObj, RES_NAME); - if (curResName != NULL && cm_str_equal(curResName, resName)) { + const char* tmpResName; + if(CheckResName(resObj, g_resNames, maxResCnt, &g_resCount, &tmpResName) != CM_SUCCESS) { + write_runlog(ERROR, "%s%s Res(%s) configure contains some error, check first.\n", GetResOperStr(resCtx->mode), + GetInstOperStr(resCtx->inst.mode), resName); + return NULL; + } + + if (tmpResName != NULL && cm_str_equal(tmpResName, resName)) { + resIndex = i; if (resIdx != NULL) { *resIdx = i; } - return resObj; } } + + if (resIndex != -1) { + return cJSON_GetArrayItem(resArray, resIndex); + } return NULL; } @@ -922,11 +942,26 @@ static cJSON *GetInstFromArray(const ResOption *resCtx, const cJSON *resArray, i return NULL; } +static bool CheckResNameForEdit(const char *value) +{ + if (strlen(value) >= CM_MAX_RES_NAME) { + write_runlog(ERROR, "resource's new name(%s) length exceeds the maximum(%d).\n", value, CM_MAX_RES_NAME); + return false; + } + for (uint32 i = 0; i < g_resCount; i++) { + if (strcmp(value, g_resNames[i]) == 0) { + write_runlog(ERROR, "resource's new name(%s) has already exist in configure.\n", value); + return false; + } + } + return true; +} + static status_t EditStringToJson( const ResOption *resCtx, cJSON *root, const char *key, const char *value, ResOpMode mode) { if (CM_IS_EMPTY_STR(key) || CM_IS_EMPTY_STR(value)) { - write_runlog(ERROR, "%s%s Res(%s) fails to add string to json, when key or value is empty.\n", + write_runlog(ERROR, "%s%s Res(%s) fails to edit string to json, when key or value is empty.\n", GetResOperStr(resCtx->mode), GetInstOperStr(resCtx->inst.mode), resCtx->resName); return CM_ERROR; } @@ -934,6 +969,17 @@ static status_t EditStringToJson( if (mode != RES_OP_EDIT) { (void)cJSON_AddStringToObject(root, key, value); } else { + uint32 index = 0; + if (cm_str_equal(key, RES_NAME) && !CheckResNameForEdit(value)){ + write_runlog(ERROR, "%s%s Res(%s) fails to edit new name to json.\n", + GetResOperStr(resCtx->mode), GetInstOperStr(resCtx->inst.mode), resCtx->resName); + return CM_ERROR; + } + if (cm_str_equal(key, RESOURCE_TYPE) && !CompareResType(value, &index)){ + write_runlog(ERROR, "%s%s Res(%s) fails to edit new resource_type to json.\n", + GetResOperStr(resCtx->mode), GetInstOperStr(resCtx->inst.mode), resCtx->resName); + return CM_ERROR; + } (void)cJSON_ReplaceItemInObject(root, key, cJSON_CreateString(value)); } return CM_SUCCESS; @@ -1164,6 +1210,11 @@ static status_t EditObjectToJson( } return CM_SUCCESS; } + if(IsKeyInRestrictList(key) && (!IsValueNumber(value) || !IsResConfValid(key, (const int)CmAtol(value, -1)))) { + write_runlog(ERROR, "%s%s Res(%s) fails to set key(%s) to new value(%s) due to wrong type or out of range.\n", + GetResOperStr(resCtx->mode), GetInstOperStr(resCtx->inst.mode), resCtx->resName, key, value); + return CM_ERROR; + } if (IsValueNumber(value)) { (void)cJSON_ReplaceItemInObject(root, key, cJSON_CreateNumber((const double)CmAtol(value, -1))); } else { diff --git a/src/cm_ctl/ctl_res_check.cpp b/src/cm_ctl/ctl_res_check.cpp index 75aa056..1ca9b80 100644 --- a/src/cm_ctl/ctl_res_check.cpp +++ b/src/cm_ctl/ctl_res_check.cpp @@ -428,7 +428,7 @@ static status_t CheckVipResInfo(cJSON *resItem, const char *resName) return CM_SUCCESS; } -static status_t CheckResName( +status_t CheckResName( const cJSON *resItem, char (*resName)[CM_MAX_RES_NAME], uint32 maxCnt, uint32 *curCnt, const char **curResName) { cJSON *objName = cJSON_GetObjectItem(resItem, RES_NAME); @@ -491,6 +491,9 @@ bool CompareResType(const char *value, uint32 *index) uint32 arrLen = (uint32)(sizeof(g_resTypeMap) / sizeof(g_resTypeMap[0])); char tmpStr[MAX_PATH_LEN] = {0}; for (uint32 i = 0; i < arrLen; ++i) { + if (g_resTypeMap[i].type == RES_TYPE_INIT || g_resTypeMap[i].type == RES_TYPE_UNKNOWN) { + continue; + } if (g_resTypeMap[i].typeStr == NULL) { continue; } diff --git a/src/include/cm/cm_ctl/ctl_res.h b/src/include/cm/cm_ctl/ctl_res.h index 5c63802..ea9f7bb 100644 --- a/src/include/cm/cm_ctl/ctl_res.h +++ b/src/include/cm/cm_ctl/ctl_res.h @@ -27,6 +27,7 @@ #include "c.h" #include "cm_defs.h" +#include "cm_misc_res.h" #include "cjson/cJSON.h" #include "cm_elog.h" @@ -153,5 +154,7 @@ bool8 IsResCheckInstances(ResType resType); bool8 IsCurNotCheckInstances(const ResOption *resCtx, const cJSON *resObj); const char *GetResTypeValue(uint32 index); ResType GetResTypeInJson(const ResOption *resCtx, const cJSON *resObj); +status_t CheckResName( + const cJSON *resItem, char (*resName)[CM_MAX_RES_NAME], uint32 maxCnt, uint32 *curCnt, const char **curResName); #endif diff --git a/src/include/cm/cm_misc_res.h b/src/include/cm/cm_misc_res.h index fe93f02..1119204 100644 --- a/src/include/cm/cm_misc_res.h +++ b/src/include/cm/cm_misc_res.h @@ -101,6 +101,7 @@ int ResConfMinValue(const char *param); const char* ResConfDefValue(const char *param); bool IsResConfValid(const char *param, int value); +bool IsKeyInRestrictList(const char *key); void GetCmConfJsonPath(char *path, uint32 pathLen); int ReadCmConfJson(void *logFunc); status_t InitAllResStat(int logLevel = LOG);