diff --git a/BUILD.gn b/BUILD.gn index a8f3527..b01dff9 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -59,6 +59,9 @@ ohos_executable("syscap_tool_bin") { if (is_mingw) { defines += [ "_POSIX_" ] } + if (defined(ohos_lite) && ohos_kernel_type == "liteos_m") { + cflags = [ "-DPATH_MAX=1024" ] + } sources = [ "./src/main.c" ] sources += sources_platform_common @@ -74,71 +77,32 @@ ohos_executable("syscap_tool_bin") { part_name = "syscap_codec" } -ohos_executable("syscap_tool_test") { - install_enable = true - include_dirs = [ "src" ] - public_configs = [ ":pubilc" ] - defines = [] - - if (is_mingw) { - defines += [ "_POSIX_" ] - } - - sources = [ "./test/syscap_tool_test.c" ] - sources += sources_platform_common - - deps = [ "//third_party/bounds_checking_function:libsec_static" ] - - if (defined(ohos_lite)) { - deps += [ "//build/lite/config/component/cJSON:cjson_static" ] - } else { - deps += [ "//third_party/cJSON:cjson_static" ] - } - - subsystem_name = "developtools" - part_name = "syscap_codec" -} - -ohos_shared_library("syscap_tool_shared") { - output_name = "syscap_codec" - include_dirs = [ "src" ] - public_configs = [ ":pubilc" ] - - sources = sources_platform_common - - deps = [ "//third_party/bounds_checking_function:libsec_static" ] - - if (defined(ohos_lite)) { - deps += [ "//build/lite/config/component/cJSON:cjson_static" ] - } else { - deps += [ "//third_party/cJSON:cjson_static" ] - } - - subsystem_name = "developtools" - part_name = "syscap_codec" -} - config("syscap_interface_public_config") { include_dirs = [ "./interfaces/inner_api/" ] } if (defined(ohos_lite)) { - shared_library("syscap_interface_shared") { - include_dirs = [ - "include", - "src", - ] - public_configs = [ ":syscap_interface_public_config" ] - sources = [ - "./interfaces/inner_api/syscap_interface.c", - "./src/endian_internal.c", - "./src/syscap_tool.c", - ] + if (ohos_kernel_type == "liteos_m") { + group("syscap_interface_shared") { + } + } else { + shared_library("syscap_interface_shared") { + include_dirs = [ + "include", + "src", + ] + public_configs = [ ":syscap_interface_public_config" ] + sources = [ + "./interfaces/inner_api/syscap_interface.c", + "./src/endian_internal.c", + "./src/syscap_tool.c", + ] - deps = [ - "//build/lite/config/component/cJSON:cjson_static", - "//third_party/bounds_checking_function:libsec_static", - ] + deps = [ + "//build/lite/config/component/cJSON:cjson_static", + "//third_party/bounds_checking_function:libsec_static", + ] + } } } else { ohos_shared_library("syscap_interface_shared") { @@ -199,7 +163,6 @@ group("syscap_codec") { ":pcid_sc", ":syscap_define_check", ":syscap_interface_shared", - ":syscap_tool_shared", ] if (support_jsapi && is_standard_system) { deps += [ "napi:systemcapability" ] diff --git a/include/syscap_define.h b/include/syscap_define.h index 9a5de08..33f161d 100644 --- a/include/syscap_define.h +++ b/include/syscap_define.h @@ -248,6 +248,19 @@ typedef enum SystemCapabilityNum { // Add here MULTIMODALINPUT_INPUT_COOPERATOR, ABILITY_ABILITYRUNTIME_QUICKFIX, + SECURITY_DLPCREDENTIALSERVICE, + BUNDLEMANAGER_BUNDLEFRAMEWORK_APPCONTROL, + BUNDLEMANAGER_BUNDLEFRAMEWORK_CORE, + BUNDLEMANAGER_BUNDLEFRAMEWORK_FREEINSTALL, + BUNDLEMANAGER_BUNDLEFRAMEWORK_LAUNCHER, + BUNDLEMANAGER_BUNDLEFRAMEWORK_DEFAULTAPP, + BUNDLEMANAGER_BUNDLEFRAMEWORK_RESOURCE, + MULTIMEDIA_AVSESSION_CORE, + MULTIMEDIA_AVSESSION_MANAGER, + MULTIMEDIA_AUDIO_TONE, + MULTIMEDIA_AUDIO_INTERRUPT, + CLOUD_AAID, + MSDP_DEVICESTATUS_STATIONARY, SYSCAP_NUM_MAX = 960 } SyscapNum; @@ -473,6 +486,20 @@ const static SyscapWithNum g_arraySyscap[] = { {"SystemCapability.Security.CryptoFramework", SECURITY_CRYPTOFRAMEWORK}, {"SystemCapability.MultimodalInput.Input.Cooperator", MULTIMODALINPUT_INPUT_COOPERATOR}, {"SystemCapability.Ability.AbilityRuntime.QuickFix", ABILITY_ABILITYRUNTIME_QUICKFIX}, + {"SystemCapability.Security.DlpCredentialService", SECURITY_DLPCREDENTIALSERVICE}, + {"SystemCapability.BundleManager.BundleFramework.AppControl", BUNDLEMANAGER_BUNDLEFRAMEWORK_APPCONTROL}, + {"SystemCapability.BundleManager.BundleFramework.Core", BUNDLEMANAGER_BUNDLEFRAMEWORK_CORE}, + {"SystemCapability.BundleManager.BundleFramework.FreeInstall", BUNDLEMANAGER_BUNDLEFRAMEWORK_FREEINSTALL}, + {"SystemCapability.BundleManager.BundleFramework.Launcher", BUNDLEMANAGER_BUNDLEFRAMEWORK_LAUNCHER}, + {"SystemCapability.BundleManager.BundleFramework.DefaultApp", + BUNDLEMANAGER_BUNDLEFRAMEWORK_DEFAULTAPP}, + {"SystemCapability.BundleManager.BundleFramework.Resource", BUNDLEMANAGER_BUNDLEFRAMEWORK_RESOURCE}, + {"SystemCapability.Multimedia.AVSession.Core", MULTIMEDIA_AVSESSION_CORE}, + {"SystemCapability.Multimedia.AVSession.Manager", MULTIMEDIA_AVSESSION_MANAGER}, + {"SystemCapability.Multimedia.Audio.Tone", MULTIMEDIA_AUDIO_TONE}, + {"SystemCapability.Multimedia.Audio.Interrupt", MULTIMEDIA_AUDIO_INTERRUPT}, + {"SystemCapability.Cloud.AAID", CLOUD_AAID}, + {"SystemCapability.Msdp.DeviceStatus.Stationary", MSDP_DEVICESTATUS_STATIONARY}, }; #ifdef __cplusplus diff --git a/interfaces/inner_api/syscap_interface.c b/interfaces/inner_api/syscap_interface.c index eeb349d..06c95ab 100644 --- a/interfaces/inner_api/syscap_interface.c +++ b/interfaces/inner_api/syscap_interface.c @@ -298,7 +298,7 @@ bool DecodePrivateSyscap(char *input, char (**output)[SINGLE_SYSCAP_LEN], int *o return true; } -static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, uint16_t *index, uint16_t indexLen) +static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, const uint16_t *index, uint16_t indexLen) { uint16_t sector, pos; diff --git a/napi/napi_query_syscap.cpp b/napi/napi_query_syscap.cpp index 5cbb3d9..858f934 100644 --- a/napi/napi_query_syscap.cpp +++ b/napi/napi_query_syscap.cpp @@ -42,7 +42,7 @@ constexpr size_t KEY_BUFFER_SIZE = 32; napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) // Async Function Set -struct systemCapabilityAsyncContext { +struct SystemCapabilityAsyncContext { napi_env env = nullptr; napi_async_work work = nullptr; char key[KEY_BUFFER_SIZE] = { 0 }; @@ -64,7 +64,7 @@ static char* getSystemCapability() uint32_t *osCapU32 = nullptr; char *priOutput = nullptr; char *temp = nullptr; - char *allSyscapBUffer = nullptr; + char *allSyscapBuffer = nullptr; char osCapArray[PCID_MAIN_U32][U32_TO_STR_MAX_LEN] = {}; char (*priCapArray)[SINGLE_SYSCAP_LEN] = nullptr; @@ -105,39 +105,39 @@ static char* getSystemCapability() sumLen += (PCID_MAIN_U32 + priCapArrayCnt + 1); // split with ',' // splicing string - allSyscapBUffer = (char *)malloc(sumLen); - if (allSyscapBUffer == nullptr) { + allSyscapBuffer = (char *)malloc(sumLen); + if (allSyscapBuffer == nullptr) { PRINT_ERR("malloc failed!"); goto FREE_PRICAP_ARRAY; } - err = memset_s(allSyscapBUffer, sumLen, 0, sumLen); + err = memset_s(allSyscapBuffer, sumLen, 0, sumLen); if (err != EOK) { PRINT_ERR("memset failed!"); - free(allSyscapBUffer); - allSyscapBUffer = nullptr; + free(allSyscapBuffer); + allSyscapBuffer = nullptr; goto FREE_PRICAP_ARRAY; } temp = *osCapArray; for (size_t i = 1; i < PCID_MAIN_U32; i++) { - retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, osCapArray[i]); + retError = sprintf_s(allSyscapBuffer, sumLen, "%s,%s", temp, osCapArray[i]); if (retError == -1) { PRINT_ERR("splicing os syscap string failed."); - free(allSyscapBUffer); - allSyscapBUffer = nullptr; + free(allSyscapBuffer); + allSyscapBuffer = nullptr; goto FREE_PRICAP_ARRAY; } - temp = allSyscapBUffer; + temp = allSyscapBuffer; } for (int i = 0; i < priCapArrayCnt; i++) { - retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, *(priCapArray + i)); + retError = sprintf_s(allSyscapBuffer, sumLen, "%s,%s", temp, *(priCapArray + i)); if (retError == -1) { PRINT_ERR("splicing pri syscap string failed."); - free(allSyscapBUffer); - allSyscapBUffer = nullptr; + free(allSyscapBuffer); + allSyscapBuffer = nullptr; goto FREE_PRICAP_ARRAY; } - temp = allSyscapBUffer; + temp = allSyscapBuffer; } FREE_PRICAP_ARRAY: @@ -145,7 +145,7 @@ FREE_PRICAP_ARRAY: FREE_PRIOUTPUT: free(priOutput); - return allSyscapBUffer; + return allSyscapBuffer; } napi_value QuerySystemCapability(napi_env env, napi_callback_info info) @@ -154,7 +154,7 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) NAPI_ASSERT(env, argc <= 1, "too many parameters"); napi_value result = nullptr; - systemCapabilityAsyncContext* asyncContext = new systemCapabilityAsyncContext(); + SystemCapabilityAsyncContext* asyncContext = new SystemCapabilityAsyncContext(); asyncContext->env = env; @@ -178,7 +178,7 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) napi_create_async_work( env, nullptr, resource, [](napi_env env, void* data) { - systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data; + SystemCapabilityAsyncContext *asyncContext = (SystemCapabilityAsyncContext *)data; char *syscapStr = getSystemCapability(); if (syscapStr != nullptr) { asyncContext->value = syscapStr; @@ -188,8 +188,8 @@ napi_value QuerySystemCapability(napi_env env, napi_callback_info info) } }, [](napi_env env, napi_status status, void* data) { - systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data; - napi_value result[2] = {0}; + SystemCapabilityAsyncContext *asyncContext = (SystemCapabilityAsyncContext *)data; + napi_value result[2] = {nullptr, nullptr}; if (!asyncContext->status) { napi_get_undefined(env, &result[0]); napi_create_string_utf8(env, asyncContext->value, strlen(asyncContext->value), &result[1]); // ? @@ -235,14 +235,14 @@ EXTERN_C_END /* * Module define */ -static napi_module systemCapabilityModule = { +static napi_module g_systemCapabilityModule = { .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = QuerryExport, .nm_modname = "systemCapability", - .nm_priv = ((void*)0), - .reserved = {0}, + .nm_priv = nullptr, + .reserved = {nullptr}, }; /* @@ -250,6 +250,6 @@ static napi_module systemCapabilityModule = { */ extern "C" __attribute__((constructor)) void systemCapabilityRegisterModule(void) { - napi_module_register(&systemCapabilityModule); + napi_module_register(&g_systemCapabilityModule); } } \ No newline at end of file diff --git a/src/create_pcid.c b/src/create_pcid.c index ab48c8b..8ef9321 100644 --- a/src/create_pcid.c +++ b/src/create_pcid.c @@ -231,8 +231,8 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) uint16_t allPriSyscapStrLen = 0; for (i = 0; i < privateCapSize; i++) { - jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, i); - allPriSyscapStrLen += strlen(strchr(jsonArrayItem->valuestring, '.') + 1); + jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, (int)i); + allPriSyscapStrLen += (uint16_t)strlen(strchr(jsonArrayItem->valuestring, '.') + 1); allPriSyscapStrLen++; // for separator ',' } if ((allPriSyscapStrLen + 1) > PRIVATE_SYSCAP_SIZE) { @@ -241,18 +241,18 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) goto FREE_CONVERT_OUT; } - uint16_t PCIDLength = sizeof(PCIDMain) + allPriSyscapStrLen + 1; - PCIDMain *PCIDBuffer = (PCIDMain *)malloc(PCIDLength); - if (PCIDBuffer == NULL) { + uint16_t pcidLength = sizeof(PCIDMain) + allPriSyscapStrLen + 1; + PCIDMain *pcidBuffer = (PCIDMain *)malloc(pcidLength); + if (pcidBuffer == NULL) { PRINT_ERR("malloc for pcid buffer failed\n"); ret = -1; goto FREE_CONVERT_OUT; } - (void)memset_s(PCIDBuffer, PCIDLength, 0, PCIDLength); + (void)memset_s(pcidBuffer, pcidLength, 0, pcidLength); // process os syscap for (i = 0; i < osCapSize; i++) { - jsonArrayItem = cJSON_GetArrayItem(jsonOsSyscapObj, i); + jsonArrayItem = cJSON_GetArrayItem(jsonOsSyscapObj, (int)i); osCapIndex = cJSON_GetObjectItem(allOsSyscapObj, jsonArrayItem->valuestring); if (osCapIndex == NULL) { PRINT_ERR("can't find the syscap: %s, please add it in syscap_define.h.\n", jsonArrayItem->valuestring); @@ -266,14 +266,14 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) ret = -1; goto FREE_PCID_BUFFER_OUT; } - PCIDBuffer->osSyscap[sectorOfBits] |= 1 << (posOfBits); + pcidBuffer->osSyscap[sectorOfBits] |= 1 << (posOfBits); } // process private syscap - char *priSyscapHead = (char *)(PCIDBuffer + 1); + char *priSyscapHead = (char *)(pcidBuffer + 1); char *priSyscapStr = NULL; for (i = 0; i < privateCapSize; i++) { - jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, i); + jsonArrayItem = cJSON_GetArrayItem(jsonPriSyscapObj, (int)i); priSyscapStr = strchr(jsonArrayItem->valuestring, '.') + 1; nRet = strcat_s(priSyscapHead, allPriSyscapStrLen + 1, priSyscapStr); nRet += strcat_s(priSyscapHead, allPriSyscapStrLen + 1, ","); @@ -290,8 +290,8 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) ret = -1; goto FREE_PCID_BUFFER_OUT; } - PCIDBuffer->apiVersion = HtonsInter((uint16_t)jsonSyscapObj->valueint); - PCIDBuffer->apiVersionType = 0; + pcidBuffer->apiVersion = HtonsInter((uint16_t)jsonSyscapObj->valueint); + pcidBuffer->apiVersionType = 0; jsonSyscapObj = cJSON_GetObjectItem(jsonRootObj, "system_type"); if (jsonSyscapObj == NULL || !cJSON_IsString(jsonSyscapObj)) { @@ -300,10 +300,10 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) goto FREE_PCID_BUFFER_OUT; } systemType = jsonSyscapObj->valuestring; - PCIDBuffer->systemType = !strcmp(systemType, "mini") ? 0b001 : + pcidBuffer->systemType = !strcmp(systemType, "mini") ? 0b001 : (!strcmp(systemType, "small") ? 0b010 : (!strcmp(systemType, "standard") ? 0b100 : 0)); - if (PCIDBuffer->systemType == 0) { + if (pcidBuffer->systemType == 0) { PRINT_ERR("\"system_type\" is invaild, systemType = \"%s\"\n", systemType); ret = -1; goto FREE_PCID_BUFFER_OUT; @@ -315,10 +315,10 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) ret = -1; goto FREE_PCID_BUFFER_OUT; } - PCIDBuffer->manufacturerID = HtonlInter((uint32_t)jsonSyscapObj->valueint); + pcidBuffer->manufacturerID = HtonlInter((uint32_t)jsonSyscapObj->valueint); const char pcidFileName[] = "PCID.sc"; - ret = ConvertedContextSaveAsFile(outDirPath, pcidFileName, (char *)PCIDBuffer, PCIDLength); + ret = ConvertedContextSaveAsFile(outDirPath, pcidFileName, (char *)pcidBuffer, pcidLength); if (ret != 0) { PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:%s\n", outDirPath, pcidFileName); ret = -1; @@ -326,7 +326,7 @@ int32_t CreatePCID(char *inputFile, char *outDirPath) } FREE_PCID_BUFFER_OUT: - free(PCIDBuffer); + free(pcidBuffer); FREE_CONVERT_OUT: free(allOsSyscapObj); FreeContextBuffer(contextBuffer); @@ -376,7 +376,7 @@ int32_t DecodePCID(char *inputFile, char *outDirPath) } nRet = memcpy_s(osSyscap, OS_SYSCAP_BYTES, (uint8_t *)pcidMain + 8, OS_SYSCAP_BYTES); // 8, bytes of pcid header - if (EOK != nRet) { + if (nRet != EOK) { PRINT_ERR("memcpy_s failed."); ret = -1; goto FREE_VECTOR_OUT; @@ -420,7 +420,7 @@ int32_t DecodePCID(char *inputFile, char *outDirPath) } char *ptrPrivateSyscap = (char *)(pcidMain + 1); - uint16_t privateSyscapLen = contextBufLen - sizeof(PCIDMain) - 1; + int privateSyscapLen = (int)(contextBufLen - sizeof(PCIDMain) - 1); char priSyscapStr[SINGLE_SYSCAP_LEN] = {0}; char *tempPriSyscapStr = priSyscapStr; char fullPriSyscapStr[SINGLE_SYSCAP_LEN] = {0}; @@ -694,15 +694,15 @@ int32_t DecodeStringPCIDToJson(char *input, char *outDirPath) PRINT_ERR("Add syscap to json failed.\n"); goto ADD_JSON_FAILED; } - if (AddHeaderToJsonObj(pcidHeader, PCID_HEADER, rootObj)) { + if (AddHeaderToJsonObj(pcidHeader, PCID_HEADER, rootObj) != 0) { PRINT_ERR("Add header to json object failed.\n"); goto ADD_JSON_FAILED; } - if (AddOsSyscapToJsonObj(osSyscapUintArray, OS_SYSCAP_NUM, sysCapObj)) { + if (AddOsSyscapToJsonObj(osSyscapUintArray, OS_SYSCAP_NUM, sysCapObj) != 0) { PRINT_ERR("Add os syscap json object failed.\n"); goto ADD_JSON_FAILED; } - if (AddPriSyscapToJsonObj(priSyscapStr, strlen(priSyscapStr), sysCapObj)) { + if (AddPriSyscapToJsonObj(priSyscapStr, (uint32_t)strlen(priSyscapStr), sysCapObj) != 0) { PRINT_ERR("Add private syscap json object failed.\n"); goto ADD_JSON_FAILED; } diff --git a/src/syscap_tool.c b/src/syscap_tool.c index 402d00d..54193ff 100644 --- a/src/syscap_tool.c +++ b/src/syscap_tool.c @@ -27,14 +27,6 @@ #include "create_pcid.h" #include "syscap_tool.h" -typedef struct ProductCompatibilityIDHead { - uint16_t apiVersion : 15; - uint16_t apiVersionType : 1; - uint16_t systemType : 3; - uint16_t reserved : 13; - uint32_t manufacturerID; -} PCIDHead; - typedef struct RequiredProductCompatibilityIDHead { uint16_t apiVersion : 15; uint16_t apiVersionType : 1; @@ -48,6 +40,7 @@ typedef struct RequiredProductCompatibilityIDHead { #define PCID_OUT_BUFFER RPCID_OUT_BUFFER #define BYTES_OF_OS_SYSCAP 120 #define U32_TO_STR_MAX_LEN 11 +#define STRING_FORMAT_LEN_MAX 1024 #define PRINT_ERR(...) \ do { \ @@ -123,12 +116,12 @@ static int32_t ConvertedContextSaveAsFile(char *outDirPath, const char *filename char path[PATH_MAX + 1] = {0x00}; #ifdef _POSIX_ - if (strlen(outDirPath) > PATH_MAX || strncpy_s(path, PATH_MAX, outDirPath, strlen(outDirPath)) != EOK) { + if (strlen(outDirPath) >= PATH_MAX || strncpy_s(path, PATH_MAX, outDirPath, strlen(outDirPath)) != EOK) { PRINT_ERR("get path(%s) failed\n", outDirPath); return -1; } #else - if (strlen(outDirPath) > PATH_MAX || realpath(outDirPath, path) == NULL) { + if (strlen(outDirPath) >= PATH_MAX || realpath(outDirPath, path) == NULL) { PRINT_ERR("get file(%s) real path failed\n", outDirPath); return -1; } @@ -170,15 +163,15 @@ static int32_t ConvertedContextSaveAsFile(char *outDirPath, const char *filename static cJSON *CreateWholeSyscapJsonObj(void) { - size_t numOfSyscapAll = sizeof(g_arraySyscap) / sizeof(SyscapWithNum); + size_t allSyscapNum = sizeof(g_arraySyscap) / sizeof(SyscapWithNum); cJSON *root = cJSON_CreateObject(); - for (size_t i = 0; i < numOfSyscapAll; i++) { + for (size_t i = 0; i < allSyscapNum; i++) { cJSON_AddItemToObject(root, g_arraySyscap[i].str, cJSON_CreateNumber(g_arraySyscap[i].num)); } return root; } -int32_t RPCIDEncode(char *inputFile, char *outDirPath) +int32_t RPCIDEncode(char *inputFile, char *outputPath) { int32_t ret; char *contextBuffer = NULL; @@ -248,7 +241,7 @@ int32_t RPCIDEncode(char *inputFile, char *outDirPath) *(uint16_t *)fillTmpPtr = HtonsInter((uint16_t)(sysCapSize * SINGLE_FEAT_LEN)); fillTmpPtr += sizeof(uint16_t); for (uint32_t i = 0; i < sysCapSize; i++) { - arrayItemPtr = cJSON_GetArrayItem(sysCapPtr, i); + arrayItemPtr = cJSON_GetArrayItem(sysCapPtr, (int)i); char *pointPos = strchr(arrayItemPtr->valuestring, '.'); if (pointPos == NULL) { PRINT_ERR("context of \"syscap\" array is invalid\n"); @@ -271,9 +264,9 @@ int32_t RPCIDEncode(char *inputFile, char *outDirPath) fillTmpPtr += SINGLE_FEAT_LEN; } - ret = ConvertedContextSaveAsFile(outDirPath, "RPCID.sc", convertedBuffer, convertedBufLen); + ret = ConvertedContextSaveAsFile(outputPath, "RPCID.sc", convertedBuffer, convertedBufLen); if (ret != 0) { - PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:rpcid.sc\n", outDirPath); + PRINT_ERR("ConvertedContextSaveAsFile failed, outputPath:%s, filename:rpcid.sc\n", outputPath); goto FREE_CONVERT_OUT; } @@ -289,6 +282,10 @@ static int32_t ParseRpcidToJson(char *input, uint32_t inputLen, cJSON *rpcidJson uint32_t i; int32_t ret = 0; uint16_t sysCapLength = NtohsInter(*(uint16_t *)(input + sizeof(uint32_t))); + if (sysCapLength > inputLen - sizeof(uint32_t)) { + PRINT_ERR("Get sysCapLength(%u) error, inputLen = %u\n", sysCapLength, inputLen); + return -1; + } uint16_t sysCapCount = sysCapLength / SINGLE_FEAT_LEN; char *sysCapBegin = input + sizeof(RPCIDHead) + sizeof(uint32_t); RPCIDHead *rpcidHeader = (RPCIDHead *)input; @@ -368,7 +365,7 @@ static int32_t CheckRpcidFormat(char *inputFile, char **Buffer, uint32_t *Len) return 0; } -int32_t RPCIDDecode(char *inputFile, char *outDirPath) +int32_t RPCIDDecode(char *inputFile, char *outputPath) { int32_t ret = 0; char *contextBuffer = NULL; @@ -383,16 +380,16 @@ int32_t RPCIDDecode(char *inputFile, char *outDirPath) // parse rpcid to json cJSON *rpcidRoot = cJSON_CreateObject(); - if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot)) { + if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot) != 0) { PRINT_ERR("Prase rpcid to json failed. Input failed: %s\n", inputFile); goto FREE_RPCID_ROOT; } // save to json file convertedBuffer = cJSON_Print(rpcidRoot); - ret = ConvertedContextSaveAsFile(outDirPath, "RPCID.json", convertedBuffer, strlen(convertedBuffer)); + ret = ConvertedContextSaveAsFile(outputPath, "RPCID.json", convertedBuffer, strlen(convertedBuffer)); if (ret != 0) { - PRINT_ERR("ConvertedContextSaveAsFile failed, outDirPath:%s, filename:rpcid.json\n", outDirPath); + PRINT_ERR("ConvertedContextSaveAsFile failed, outputPath:%s, filename:rpcid.json\n", outputPath); goto FREE_RPCID_ROOT; } @@ -403,7 +400,7 @@ FREE_CONTEXT_OUT: return ret; } -static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, uint16_t *index, uint16_t indexLen) +static int SetOsSysCapBitMap(uint8_t *out, uint16_t outLen, const uint16_t *index, uint16_t indexLen) { uint16_t sector, pos; @@ -429,7 +426,6 @@ int32_t EncodeRpcidscToString(char *inputFile, char *outDirPath) int32_t ret = 0; int32_t sysCapArraySize; uint32_t bufferLen, i; - uint16_t indexOs = 0; uint16_t indexPri = 0; uint16_t *osSysCapIndex; char *contextBuffer = NULL; @@ -448,7 +444,7 @@ int32_t EncodeRpcidscToString(char *inputFile, char *outDirPath) // parse rpcid to json rpcidRoot = cJSON_CreateObject(); - if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot)) { + if (ParseRpcidToJson(contextBuffer, bufferLen, rpcidRoot) != 0) { PRINT_ERR("Prase rpcid to json failed. Input file: %s\n", inputFile); goto FREE_RPCID_ROOT; } @@ -474,16 +470,17 @@ int32_t EncodeRpcidscToString(char *inputFile, char *outDirPath) (void)memset_s(osSysCapIndex, sizeof(uint16_t) * sysCapArraySize, 0, sizeof(uint16_t) * sysCapArraySize); // malloc for save private syscap string - priSyscapArray = (char *)malloc(sysCapArraySize * SINGLE_SYSCAP_LEN); + priSyscapArray = (char *)malloc((uint32_t)sysCapArraySize * SINGLE_SYSCAP_LEN); if (priSyscapArray == NULL) { PRINT_ERR("malloc(%d) failed.\n", sysCapArraySize * SINGLE_SYSCAP_LEN); goto FREE_MALLOC_OSSYSCAP; } - (void)memset_s(priSyscapArray, sysCapArraySize * SINGLE_SYSCAP_LEN, - 0, sysCapArraySize * SINGLE_SYSCAP_LEN); + (void)memset_s(priSyscapArray, (size_t)(sysCapArraySize * SINGLE_SYSCAP_LEN), + 0, (size_t)(sysCapArraySize * SINGLE_SYSCAP_LEN)); priSyscap = priSyscapArray; // part os syscap and ptivate syscap - for (i = 0; i < (uint32_t)sysCapArraySize; i++) { + uint16_t indexOs = 0; + for (int i = 0; i < sysCapArraySize; i++) { cJSON *cJsonItem = cJSON_GetArrayItem(sysCapArray, i); cJsonTemp = cJSON_GetObjectItem(sysCapDefine, cJsonItem->valuestring); if (cJsonTemp != NULL) { @@ -565,7 +562,7 @@ int32_t SeparateSyscapFromString(const char *inputString, uint32_t *osArray, uin { int32_t ret = 0; uint32_t i; - size_t inputLen = strlen(inputString); + uint32_t count = 0; char *temp = NULL; char *tok = NULL; @@ -576,7 +573,16 @@ int32_t SeparateSyscapFromString(const char *inputString, uint32_t *osArray, uin } // copy to temp string input - char *input = (char *)malloc(strlen(inputString) + 1); + if (inputString == NULL) { + PRINT_ERR("inputString is null.\n"); + return -1; + } + size_t inputLen = strlen(inputString); + if (inputLen > STRING_FORMAT_LEN_MAX) { + PRINT_ERR("input string too long(%zu).\n", inputLen); + return -1; + } + char *input = (char *)malloc(inputLen + 1); if (input == NULL) { PRINT_ERR("malloc failed.\n"); return -1; @@ -658,6 +664,7 @@ int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile, uint32_t typ bool priSysFound; uint32_t pcidOsAarry[PCID_OUT_BUFFER] = {0}; uint32_t rpcidOsAarry[PCID_OUT_BUFFER] = {0}; + const size_t allSyscapNum = sizeof(g_arraySyscap) / sizeof(SyscapWithNum); if (type == TYPE_FILE) { if (GetFileContext(pcidFile, &pcidContent, &pcidContentLen)) { @@ -700,9 +707,13 @@ int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile, uint32_t typ continue; } for (uint8_t k = 0; k < INT_BIT; k++) { - if (temp2 & (0x1 << k)) { - // 2, header of pcid & rpcid - printf("Missing: %s\n", g_arraySyscap[(i - 2) * INT_BIT + k].str); + if (!(temp2 & (0x1 << k))) { + continue; + } + // 2, header of pcid & rpcid + size_t pos = (size_t)((i - 2) * INT_BIT + k); + if (pos < allSyscapNum) { + printf("Missing: %s\n", g_arraySyscap[pos].str); ossyscapFlag += 1; } } @@ -730,4 +741,4 @@ int32_t ComparePcidWithRpcidString(char *pcidFile, char *rpcidFile, uint32_t typ printf("Fail! The pcid does not meet the rpcid\n"); } return 0; -} \ No newline at end of file +} diff --git a/test/syscap_define_check.c b/test/syscap_define_check.c index 9ae0ca1..c063bd0 100644 --- a/test/syscap_define_check.c +++ b/test/syscap_define_check.c @@ -25,7 +25,7 @@ int main(void) for (size_t i = 0; i < size; i++) { if (g_arraySyscap[i].num != i) { - printf("[Error][syscap_define.h]: %s -> num(%u) should be %lu.\n", + printf("[Error][syscap_define.h]: %s -> num(%u) should be %zu.\n", g_arraySyscap[i].str, g_arraySyscap[i].num, i); flag++; } diff --git a/test/syscap_tool_test.c b/test/syscap_tool_test.c deleted file mode 100644 index acf45d1..0000000 --- a/test/syscap_tool_test.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "syscap_tool.h" -#include "create_pcid.h" - -char *g_testFilePcid = "{\n \"api_version\": 0,\n \"manufacturer_id\": 0,\n \"product\": \"rk3568\",\n" \ - " \"syscap\": {\n \"os\": [\n \"SystemCapability.Account.AppAccount\",\n" \ - " \"SystemCapability.Account.OsAccount\"\n ]\n },\n" \ - " \"system_type\": \"standard\"\n}"; -char *g_testFileRpcid = "{\n \"api_version\": 7,\n \"syscap\": [\n \"SystemCapability.hiviewdfx.hilog\",\n" \ - " \"SystemCapability.communication.softbus\",\n \"SystemCapability.hisicon.flashlight\"\n ]\n}"; - -int32_t PrepareTestFile(char *fileName, char *fileContext) -{ - int32_t ret; - FILE *fp = fopen(fileName, "wb"); - if (fp == NULL) { - return -1; - } - size_t len = fwrite(fileContext, 1, strlen(fileContext), fp); - if (len != strlen(fileContext)) { - (void)fclose(fp); - return -1; - } - ret = fclose(fp); - if (ret != 0) { - return -1; - } - return 0; -} - -int main(int argc, char **argv) -{ - int32_t status; - - char *pcidFileName = "SystemCapability.json"; - char *rpcidFileName = "rpcid.json"; - printf("###start syscap tool test###\n"); - - (void)unlink(pcidFileName); - (void)unlink(rpcidFileName); - (void)unlink("./rk3568.sc"); - (void)unlink("./newPCID.sc"); - (void)unlink("./rpcid.sc"); - (void)unlink("./rk3568.json"); - - pid_t pid = fork(); - if (pid == 0) { - printf("prepare test file...\n"); - int32_t passCnt = 0; - int32_t ret = PrepareTestFile(pcidFileName, g_testFilePcid); - if (ret != 0) { - printf(" error: prepare pcid file failed\n"); - exit(passCnt); - } - ret = PrepareTestFile(rpcidFileName, g_testFileRpcid); - if (ret != 0) { - printf(" error: prepare rpcid file failed\n"); - exit(passCnt); - } - printf("1.test rpcid.json encode to rpcid.sc\n"); - ret = RPCIDEncode(rpcidFileName, "./"); - if (ret != 0) { - printf(" error: rpcid.json encode failed\n"); - exit(passCnt); - } - passCnt++; - printf("pass\n"); - printf("2.test rpcid.sc decode to rpcid.json\n"); - ret = RPCIDDecode("rpcid.sc", "./"); - if (ret != 0) { - printf(" error: rpcid.sc decode failed\n"); - exit(passCnt); - } - passCnt++; - printf("pass\n"); - printf("3.test pcid.json encode to pcid.sc\n"); - ret = PCIDEncode(pcidFileName, "./"); - if (ret != 0) { - printf(" error: pcid.json encode failed\n"); - exit(passCnt); - } - passCnt++; - printf("pass\n"); - printf("4.test pcid.sc decode to pcid.json\n"); - ret = PCIDDecode("./rk3568.sc", "./"); - if (ret != 0) { - printf(" error: pcid.sc decode failed\n"); - exit(passCnt); - } - passCnt++; - printf("pass\n"); - printf("5.test pcid.json encode to new PCID.sc\n"); - ret = CreatePCID("./newPCID.sc", "./"); - if (ret != 0) { - printf(" error: new pcid.sc encode failed\n"); - exit(passCnt); - } - passCnt++; - printf("pass\n"); - printf("6.test new pcid.sc decode to pcid.json\n"); - ret = PCIDDecode("./newPCID.sc", "./"); - if (ret != 0) { - printf(" error: new pcid.sc decode failed\n"); - exit(passCnt); - } - passCnt++; - printf("pass\n"); - exit(passCnt); - } - (void)wait(&status); - printf("summary: total 4 passed %d\n", WEXITSTATUS(status)); - (void)unlink(pcidFileName); - (void)unlink(rpcidFileName); - (void)unlink("./rk3568.sc"); - (void)unlink("./newPCID.sc"); - (void)unlink("./rpcid.sc"); - (void)unlink("./rk3568.json"); - - return 0; -} \ No newline at end of file diff --git a/test/unittest/common/BUILD.gn b/test/unittest/common/BUILD.gn index 15937b3..4c431f5 100644 --- a/test/unittest/common/BUILD.gn +++ b/test/unittest/common/BUILD.gn @@ -11,51 +11,55 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//build/lite/config/component/lite_component.gni") if (defined(ohos_lite)) { - import("//build/lite/config/component/lite_component.gni") import("//build/lite/config/test.gni") - test_output_root = "$root_out_dir/test/unittest/syscap_codec" - executable("test_syscap_napi_unittest") { - output_extension = "bin" - output_dir = test_output_root + if (ohos_kernel_type != "liteos_m") { + test_output_root = "$root_out_dir/test/unittest/syscap_codec" - include_dirs = [ - "//commonlibrary/c_utils/base/include", - "//third_party/node/src", - "//third_party/googletest/include", - "//developtools/syscap_codec/src/", - "//developtools/syscap_codec/include/", - "//developtools/syscap_codec/interfaces/inner_api/", - "//developtools/syscap_codec/test/unittest/common/include/", - ] + executable("test_syscap_napi_unittest") { + output_extension = "bin" + output_dir = test_output_root - cflags = [ "-g3" ] + include_dirs = [ + "//commonlibrary/c_utils/base/include", + "//third_party/node/src", + "//third_party/googletest/include", + "//developtools/syscap_codec/src/", + "//developtools/syscap_codec/include/", + "//developtools/syscap_codec/interfaces/inner_api/", + "//developtools/syscap_codec/test/unittest/common/include/", + ] - sources = [ - "//developtools/syscap_codec/interfaces/inner_api/syscap_interface.c", - "//developtools/syscap_codec/src/create_pcid.c", - "//developtools/syscap_codec/src/endian_internal.c", - "//developtools/syscap_codec/src/syscap_tool.c", - "syscap_codec_test.cpp", - ] + cflags = [ "-g3" ] - defines = [ "NAPI_TEST" ] + sources = [ + "//developtools/syscap_codec/interfaces/inner_api/syscap_interface.c", + "//developtools/syscap_codec/src/create_pcid.c", + "//developtools/syscap_codec/src/endian_internal.c", + "//developtools/syscap_codec/src/syscap_tool.c", + "syscap_codec_test.cpp", + ] - deps = [ - "//base//hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", - "//test/developertest/third_party/lib/cpp:gtest_main", - "//third_party/bounds_checking_function:libsec_static", - ] + defines = [ "NAPI_TEST" ] - deps += [ "//build/lite/config/component/cJSON:cjson_static" ] + deps = [ + "//base//hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", + "//test/testfwk/developer_test/third_party/lib/cpp:gtest_main", + "//third_party/bounds_checking_function:libsec_static", + ] + + deps += [ "//build/lite/config/component/cJSON:cjson_static" ] + } } group("unittest") { - deps = [ ":test_syscap_napi_unittest" ] + if (ohos_kernel_type != "liteos_m") { + deps = [ ":test_syscap_napi_unittest" ] + } } } else { - import("//build/lite/config/component/lite_component.gni") import("//build/ohos.gni") import("//build/test.gni") diff --git a/tools/syscap_check.py b/tools/syscap_check.py old mode 100755 new mode 100644 index dc1c2de..e2b97fa --- a/tools/syscap_check.py +++ b/tools/syscap_check.py @@ -1,289 +1,309 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2022 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import json -import re -import argparse -from prettytable import PrettyTable, ALL - -table = PrettyTable() -table.hrules = ALL - - -def get_args(): - parser = argparse.ArgumentParser(add_help=True) - parser.add_argument( - "-p", - "--project_path", - default=r"./", - type=str, - help="root path of project. default: ./", - ) - parser.add_argument( - "-t", - "--check_target", - type=str, - choices=["component_codec", "component_sdk", "sdk_codec"], - required=True, - help="the target to be compared", - ) - parser.add_argument( - "-b", - "--bundles", - nargs="*", - type=str, - help="option take effect only when the check_target is component_codec. allow multiple json file. " - "default: all bundle.json file", - ) - args = parser.parse_args() - return args - - -def list_to_multiline(target_list): - return str(target_list).lstrip("[").rstrip("]").replace(", ", "\n") - - -def add_dict_as_table_row(f_table, d_dict): - s_keys = sorted(list(d_dict.keys())) - for k in s_keys: - f_table.add_row([k, list_to_multiline(sorted(list(d_dict.get(k))))]) - - -def read_value_from_json(filepath, key_hierarchy, result_dict): - if os.path.exists(filepath) is False: - print('error: file "{}" not exists.'.format(filepath)) - return result_dict - if os.path.isfile(filepath) is False: - print('error: "{}" is not a file.') - return result_dict - with open(filepath, "r") as f: - data = json.load(f) - for key in key_hierarchy: - try: - data = data[key] - except KeyError: - print( - 'warning: can\'t find the key:"{}" in file "{}"'.format( - key, filepath - ) - ) - return result_dict - finally: - f.close() - data = [x.split("=")[0].strip() for x in data if len(x) != 0 and x.isspace() is False] - if len(data) != 0: - result_dict[filepath] = data - return result_dict - - -def collect_syscap_from_codec(filepath): - array_syscap_set = set() - pattern = r'{"(.*)"' - with open(filepath, "r") as f: - for line in f: - syscap = re.search(pattern, line.strip()) - if syscap is not None: - array_syscap_set.add(syscap.group(0).lstrip("{").strip('"')) - return array_syscap_set - - -def collect_syscap_from_component(project_path, bundles=None): - result_dict = dict() - key_heirarchy = ["component", "syscap"] - if bundles is None: - subsystem_list = [ - x - for x in os.listdir(project_path) - if os.path.isdir(os.path.join(project_path, x)) and x != "out" - ] - for ss in subsystem_list: - output = os.popen( - "find {} -name bundle.json".format(os.path.join(project_path, ss)) - ) - for line in output: - read_value_from_json(line.strip(), key_heirarchy, result_dict) - else: - for b in bundles: - result_dict = read_value_from_json(b, key_heirarchy, result_dict) - result_set = set() - for v in result_dict.values(): - result_set.update(v) - return result_set, result_dict - - -def collect_syscap_from_sdk(project_path): - full_path = os.path.join(project_path, "interface", "sdk-js", "api") - ts_list = [ - os.path.join(full_path, x) for x in os.listdir(full_path) if x.endswith(".d.ts") - ] - syscap_dict = dict() - pattern = r"\* *@syscap +(.*)" - syscap_set = set() - for ts in ts_list: - with open(ts, "r") as f: - sub_set = set() - for line in f: - syscap = re.search(pattern, line) - if syscap is not None: - ss = syscap.group(0).strip().lstrip(r"\* @syscap ").strip() - sub_set.add(ss) - syscap_dict[ts] = sub_set - for v in syscap_dict.values(): - syscap_set.update(v) - return syscap_set, syscap_dict - - -def find_files_containes_value(value_set, file_values_dict): - value_files_dict = dict() - for v in value_set: - filename_set = set() - for file in file_values_dict.keys(): - if v in file_values_dict[file]: - filename_set.add(file) - if 0 != len(filename_set): - value_files_dict[v] = filename_set - return value_files_dict - - -def check_component_and_codec(project_path, bundles=None): - if bundles is not None and len(bundles) > 0: - component_syscap_set, component_syscap_dict = collect_syscap_from_component( - project_path, bundles - ) - else: - component_syscap_set, component_syscap_dict = collect_syscap_from_component( - project_path - ) - array_syscap_set = collect_syscap_from_codec( - os.path.join( - project_path, "developtools", "syscap_codec", "include", "syscap_define.h" - ) - ) - component_diff_array = component_syscap_set.difference(array_syscap_set) - value_files_dict = find_files_containes_value( - component_diff_array, component_syscap_dict - ) - array_diff_component = array_syscap_set.difference(component_syscap_set) - if 0 == len(component_diff_array) and 0 == len(array_diff_component): - table.clear() - table.field_names = ["Component and Codec are Consistent"] - print(table) - return - if 0 != len(component_diff_array): - table.field_names = ["Syscap Only in Component", "Files"] - add_dict_as_table_row(table, value_files_dict) - elif 0 == len(component_diff_array): - table.field_names = ["All Syscap in Component have been Covered by Codec"] - print("\n") - print(table) - table.clear() - if 0 != len(array_diff_component): - table.field_names = ["SysCap Only in Codec"] - table.add_row([list_to_multiline(sorted(list(array_diff_component)))]) - elif 0 == len(array_diff_component): - table.field_names = ["All SysCap in Codec have been Covered by Component"] - print("\n") - print(table) - - -def check_component_and_sdk(project_path): - component_syscap_set, component_syscap_dict = collect_syscap_from_component( - project_path - ) - ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(project_path) - ts_diff_component = ts_syscap_set.difference(component_syscap_set) - value_ts_dict = find_files_containes_value(ts_diff_component, ts_syscap_dict) - component_diff_ts = component_syscap_set.difference(ts_syscap_set) - value_component_dict = find_files_containes_value( - component_diff_ts, component_syscap_dict - ) - if 0 == len(ts_diff_component) and 0 == len(component_diff_ts): - table.clear() - table.field_names = ["SDK and Component are Consistent"] - print(table) - return - table.clear() - if 0 != len(component_diff_ts): - table.field_names = ["SysCap Only in Component", "Files"] - add_dict_as_table_row(table, value_component_dict) - elif 0 == len(component_diff_ts): - table.field_names = ["SysCap in Component have been Covered by SDK"] - print("\n") - print(table) - table.clear() - if 0 != len(ts_diff_component): - table.field_names = ["SysCap Only in SDK", "Files"] - add_dict_as_table_row(table, value_ts_dict) - elif 0 == len(ts_diff_component): - table.field_names = ["All SysCap in SDK have been Covered by Component"] - print("\n") - print(table) - - -def check_sdk_and_codec(project_path): - ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(project_path) - array_syscap_set = collect_syscap_from_codec( - os.path.join( - project_path, "developtools", "syscap_codec", "include", "syscap_define.h" - ) - ) - ts_diff_array = ts_syscap_set.difference(array_syscap_set) - value_ts_dict = find_files_containes_value(ts_diff_array, ts_syscap_dict) - array_diff_ts = array_syscap_set.difference(ts_syscap_set) - if 0 == len(ts_diff_array) and 0 == len(array_diff_ts): - table.clear() - table.field_names = ["SDK and Codec are Consistent"] - print(table) - return - table.clear() - if 0 != len(ts_diff_array): - table.field_names = ["SysCap Only in SDK", "Files"] - add_dict_as_table_row(table, value_ts_dict) - elif 0 == len(ts_diff_array): - table.field_names = ["SysCap in SDK have been Covered by Codec"] - print("\n") - print(table) - table.clear() - if 0 != len(array_diff_ts): - table.field_names = ["SysCap Only in Codec"] - table.add_row([list_to_multiline(sorted(list(array_diff_ts)))]) - elif 0 == len(array_diff_ts): - table.field_names = ["SysCap in Codec have been Covered by SDK"] - print("\n") - print(table) - - -def main(): - args = get_args() - project_path = args.project_path - check_target = args.check_target - bundles = args.bundles - if "component_codec" == check_target: - if bundles is None: - check_component_and_codec(project_path) - else: - if 0 == len(bundles): - print(r"error: '--bundles' parameter is specified, but has no value") - else: - check_component_and_codec(project_path, bundles) - elif "component_sdk" == check_target: - check_component_and_sdk(project_path) - elif "sdk_codec" == check_target: - check_sdk_and_codec(project_path) - - -if __name__ == "__main__": - main() +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import json +import re +import argparse +from prettytable import PrettyTable, ALL + + +def get_args(): + parser = argparse.ArgumentParser(add_help=True) + parser.add_argument( + "-p", + "--project_path", + default=r"./", + type=str, + help="root path of project. default: ./", + ) + parser.add_argument( + "-t", + "--check_target", + type=str, + choices=["component_codec", "component_sdk", "sdk_codec"], + required=True, + help="the target to be compared", + ) + parser.add_argument( + "-b", + "--bundles", + nargs="*", + type=str, + help="option take effect only when the check_target is component_codec. allow multiple json file. " + "default: all bundle.json file", + ) + args = parser.parse_args() + return args + + +def list_to_multiline(target_list: list): + return str(target_list).lstrip("[").rstrip("]").replace(", ", "\n") + + +def convert_set_to_sorted_list(target_set) -> list: + return sorted(list(target_set)) + + +def add_dict_as_table_row(f_table: PrettyTable, d_dict: dict, out_converter=list_to_multiline) -> None: + s_keys = convert_set_to_sorted_list(d_dict.keys()) + for i, k in enumerate(s_keys): + f_table.add_row([i + 1, k, out_converter(convert_set_to_sorted_list(d_dict.get(k)))]) + + +def bundle_syscap_post_handler(syscap: str) -> str: + return syscap.split('=')[0].strip() + + +def read_value_from_json(filepath: str, + key_hierarchy: tuple, + result_dict: dict, + post_handler=None + ) -> None: + if os.path.exists(filepath) is False: + print('error: file "{}" not exist.'.format(filepath)) + return + if not os.path.isfile(filepath): + print('error: "{}" is not a file.') + return + with open(filepath, 'r', encoding='utf-8') as f: + data = json.load(f) + for key in key_hierarchy: + try: + data = data[key] + except KeyError: + return + finally: + pass + data = [post_handler(x) for x in data if len(x) != 0 and not x.isspace()] + if len(data) != 0: + result_dict[filepath] = data + + +def collect_syscap_from_codec(filepath: str, pattern: str = r'{"(.*)"') -> tuple: + """ + 从syscap_define.h收集syscap + :param filepath: 文件的路径 + :param pattern: 匹配syscap的规则 + :return: syscap_define.h中声明的syscap集合 + """ + array_syscap_set = set() + array_syscap_dict = dict() + ptrn = re.compile(pattern) + with open(filepath, "r") as f: + content = f.read() + array_syscap_set.update(re.findall(ptrn, content)) + array_syscap_dict[filepath] = list() + for v in array_syscap_set: + array_syscap_dict.get(filepath).append(v) + return array_syscap_set, array_syscap_dict + + +def collect_syscap_from_component(project_path: str, + black_dirs: tuple, + key_heirarchy: tuple, + bundles: list = None, + ) -> tuple: + """ + 从部件的bundle.json中收集syscap + :param project_path: 项目根路径 + :param black_dirs: 根路径下的一级目录的黑名单,不扫描这些bundle.json下面的内容 + :param key_heirarchy: bundle.json中syscap所在的key的元组 + :param bundles: 指定的bundle.json + :return: syscap_set,文件名和其syscap list组成的dict + """ + result_dict = dict() + if bundles is None: + search_dir_list = [ + os.path.join(project_path, x) + for x in os.listdir(project_path) + if os.path.isdir(os.path.join(project_path, x)) and x not in black_dirs + ] + for folder in search_dir_list: + output = os.popen("find {} -name bundle.json".format(folder)) + for line in output: + line = line.strip() + read_value_from_json(line, key_heirarchy, result_dict, post_handler=bundle_syscap_post_handler) + else: + for bundle in bundles: + read_value_from_json(bundle, key_heirarchy, result_dict, post_handler=bundle_syscap_post_handler) + result_set = set() + for v in result_dict.values(): + result_set.update(v) + return result_set, result_dict + + +def sdk_syscap_post_handler(syscap: str) -> str: + return syscap.strip().lstrip("*").lstrip().lstrip("*@syscap").strip() + + +def collect_syscap_from_sdk(ts_path: str, + pattern: str = r"\* *@syscap +((?i)SystemCapability\..*)", + post_handler=None + ) -> tuple: + """ + 从sdk下的*.d.ts中收集syscap + :param ts_path: ts文件的所在路径 + :param pattern: 匹配syscap的pattern + :param post_handler: 对匹配到的syscap进行后置处理 + :return: syscap_set,和由文件名、syscap list组成的dict + """ + ts_list = list() + for item in os.listdir(ts_path): + file_path = os.path.join(ts_path, item) + if file_path.endswith(".d.ts") and os.path.isfile(file_path): + ts_list.append(file_path) + syscap_dict = dict() + ptrn = re.compile(pattern) + for ts in ts_list: + with open(ts, 'r') as f: + content = f.read() + sub_syscap_list = re.findall(ptrn, content) + sub_syscap_set = set() + for syscap in sub_syscap_list: + sub_syscap_set.add(post_handler(syscap)) + syscap_dict[ts] = sub_syscap_set + syscap_set = set() + for v in syscap_dict.values(): + syscap_set.update(v) + return syscap_set, syscap_dict + + +def find_files_containes_value(value_set: set, file_values_dict: dict) -> dict: + """ + 查看包含指定值的文件 + :param value_set: 指定值 + :param file_values_dict: 文件和值组成的dict + :return: 值和文件组成的dict + """ + value_files_dict = dict() + for v in value_set: + filename_set = set() + for file in file_values_dict.keys(): + if v in file_values_dict[file]: + filename_set.add(file) + if 0 != len(filename_set): + value_files_dict[v] = filename_set + return value_files_dict + + +def mutual_diff(a_set: set, b_set: set) -> tuple: + return a_set.difference(b_set), b_set.difference(a_set) + + +def print_inconsistent(diff_set: set, a_name: str, b_name: str, table: PrettyTable, + value_file_dict: dict) -> None: + table.clear() + if len(diff_set) != 0: + table.field_names = ["index", "SysCap only in {}".format(a_name), "Files"] + add_dict_as_table_row(table, value_file_dict) + elif len(diff_set) == 0: + table.field_names = ["All SysCap in {} have been Covered by {}".format(a_name, b_name)] + print(table) + print() + + +def print_consistent(a_diff_b_set: set, b_diff_a_set: set, table: PrettyTable, a_name: str, b_name: str) -> bool: + if len(a_diff_b_set) == 0 and len(b_diff_a_set) == 0: + table.field_names = ["{} and {} are Consistent".format(a_name, b_name)] + print(table) + print() + return True + return False + + +def print_check_result(a_diff_b_set: set, + b_diff_a_set: set, + a_name: str, + b_name: str, + a_value_file_dict: dict, + b_value_file_dict: dict, + ) -> None: + f_table = PrettyTable() + f_table.hrules = ALL + consistent_flag = print_consistent(a_diff_b_set, b_diff_a_set, f_table, a_name, b_name) + if not consistent_flag: + print_inconsistent(a_diff_b_set, a_name, b_name, f_table, a_value_file_dict) + print_inconsistent(b_diff_a_set, b_name, a_name, f_table, b_value_file_dict) + + +def check_component_and_codec(project_path, syscap_define_path: str, component_black_dirs: tuple, + bundle_key_heirarchy: tuple, bundles=None): + component_syscap_set, component_syscap_dict = collect_syscap_from_component( + project_path, black_dirs=component_black_dirs, key_heirarchy=bundle_key_heirarchy, bundles=bundles + ) + array_syscap_set, array_syscap_dict = collect_syscap_from_codec(syscap_define_path) + component_diff_array, array_diff_component = mutual_diff(component_syscap_set, array_syscap_set) + value_component_dict = find_files_containes_value( + component_diff_array, component_syscap_dict + ) + value_h_dict = find_files_containes_value(array_diff_component, array_syscap_dict) + print_check_result(component_diff_array, array_diff_component, a_name="Component", b_name="Codec", + a_value_file_dict=value_component_dict, b_value_file_dict=value_h_dict) + + +def check_component_and_sdk(project_path, component_black_dirs: tuple, component_key_heirarchy: tuple, sdk_path: str): + component_syscap_set, component_syscap_dict = collect_syscap_from_component( + project_path, black_dirs=component_black_dirs, key_heirarchy=component_key_heirarchy + ) + ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(ts_path=sdk_path, + post_handler=sdk_syscap_post_handler) + component_diff_ts, ts_diff_component = mutual_diff(component_syscap_set, ts_syscap_set) + value_ts_dict = find_files_containes_value(ts_diff_component, ts_syscap_dict) + value_component_dict = find_files_containes_value( + component_diff_ts, component_syscap_dict + ) + print_check_result(component_diff_ts, ts_diff_component, a_name="Component", b_name="SDK", + a_value_file_dict=value_component_dict, b_value_file_dict=value_ts_dict) + + +def check_sdk_and_codec(syscap_define_path: str, sdk_path: str) -> None: + ts_syscap_set, ts_syscap_dict = collect_syscap_from_sdk(ts_path=sdk_path, + post_handler=sdk_syscap_post_handler) + array_syscap_set, array_syscap_dict = collect_syscap_from_codec(syscap_define_path) + ts_diff_array, array_diff_ts = mutual_diff(ts_syscap_set, array_syscap_set) + value_ts_dict = find_files_containes_value(ts_diff_array, ts_syscap_dict) + value_h_dict = find_files_containes_value(array_diff_ts, array_syscap_dict) + print_check_result(ts_diff_array, array_diff_ts, a_name="SDK", b_name="Codec", a_value_file_dict=value_ts_dict, + b_value_file_dict=value_h_dict) + + +def main(): + args = get_args() + project_path = args.project_path + check_target = args.check_target + bundles = args.bundles + syscap_define_path = os.path.join(project_path, "developtools", "syscap_codec", "include", "syscap_define.h") + ts_path = os.path.join(project_path, "interface", "sdk-js", "api") + component_black_dirs = ("out",) + bundle_syscap_heirarchy = ("component", "syscap") + if (bundles is not None or (bundles is not None and len(bundles) != 0)) and check_target != "component_codec": + print("error: --bundles could only be used with -t component_codec") + return + if "component_sdk" == check_target: + check_component_and_sdk(project_path, component_black_dirs, bundle_syscap_heirarchy, sdk_path=ts_path) + elif "sdk_codec" == check_target: + check_sdk_and_codec(syscap_define_path=syscap_define_path, sdk_path=ts_path) + elif "component_codec" == check_target: + if bundles is not None and len(bundles) == 0: + print(r"error: '--bundles' parameter is specified, but has no value") + else: + check_component_and_codec(project_path, syscap_define_path, component_black_dirs=component_black_dirs, + bundle_key_heirarchy=bundle_syscap_heirarchy, bundles=bundles) + + +if __name__ == "__main__": + main() +