扫描问题修改

Signed-off-by: zhu-feimo <zhufeimo1@huawei.com>

AI[53%] Human Fixed[0%] Human[47%] AI Adopted[100%]
This commit is contained in:
zhu-feimo
2026-07-27 17:39:49 +08:00
parent e43b884884
commit 7e7823aae2
29 changed files with 628 additions and 356 deletions
@@ -41,6 +41,7 @@ ohos_source_set("function_info") {
sources = [
"src/function_info.cpp",
"src/raw_data_utils.cpp",
]
external_deps = [
@@ -86,8 +86,9 @@ public:
* @brief Convert vector of FunctionInfo to FunctionsRawData
* @param functions Input vector of FunctionInfo
* @param rawData Output FunctionsRawData
* @return int32_t ERR_OK on success, ERR_INVALID_VALUE if count exceeds the maximum
*/
static void FromFunctionInfoVec(const std::vector<FunctionInfo> &functions, FunctionsRawData &rawData);
static int32_t FromFunctionInfoVec(const std::vector<FunctionInfo> &functions, FunctionsRawData &rawData);
/**
* @brief Convert FunctionsRawData to vector of FunctionInfo
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2026 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_RAW_DATA_UTILS_H
#define OHOS_ABILITY_RUNTIME_RAW_DATA_UTILS_H
#include <cstdint>
#include <sstream>
#include <string>
#include <nlohmann/json.hpp>
#include "cli_error_code.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace CliTool {
// Read exactly len bytes into buf; returns false if the stream enters a failed state.
inline bool ReadRaw(std::stringstream &ss, void *buf, std::streamsize len)
{
ss.read(reinterpret_cast<char *>(buf), len);
return static_cast<bool>(ss);
}
int32_t ReadItemToJson(std::stringstream &ss, uint32_t ssLength, bool allowComments,
int32_t parseFailCode, nlohmann::json &out);
template <typename T>
int32_t ReadOneItem(std::stringstream &ss, uint32_t ssLength, T &out,
bool allowComments, int32_t parseFailCode)
{
nlohmann::json j;
int32_t ret = ReadItemToJson(ss, ssLength, allowComments, parseFailCode, j);
if (ret != ERR_OK) {
return ret;
}
if (!T::ParseFromJson(j, out)) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to parse item from JSON");
return parseFailCode;
}
return ERR_OK;
}
} // namespace CliTool
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_RAW_DATA_UTILS_H
@@ -15,6 +15,7 @@
#include "function_info.h"
#include <cstdint>
#include <cstring>
#include <memory>
#include <securec.h>
@@ -23,9 +24,12 @@
#include "cli_error_code.h"
#include "hilog_tag_wrapper.h"
#include "raw_data_utils.h"
namespace {
constexpr uint32_t MAX_FUNCTION_INFO_COUNT = 10000; // Maximum number of functions in single transfer
constexpr uint32_t MAX_FUNCTION_INFO_COUNT = 200 * 1000; // Maximum number of function info (200 * 1000)
constexpr uint32_t MAX_SCHEMA_STRING_LENGTH = 16 * 1024; // Maximum length of inputSchema/outputSchema (16KB)
constexpr uint32_t MAX_RAW_DATA_SIZE = 128 * 1024 * 1024; // Shared memory cap for FunctionsRawData (128MB)
}
namespace OHOS {
@@ -56,6 +60,11 @@ bool ParseInputSchema(const nlohmann::json &json, std::string &output)
if (inputSchema.is_string()) {
output = inputSchema.get<std::string>();
if (!output.empty()) {
if (output.size() > MAX_SCHEMA_STRING_LENGTH) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "ParseFromJson failed: inputSchema too long: %{public}u, max: %{public}u",
static_cast<uint32_t>(output.size()), MAX_SCHEMA_STRING_LENGTH);
return false;
}
nlohmann::json parsed = nlohmann::json::parse(output, nullptr, false);
if (parsed.is_discarded()) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "ParseFromJson failed: inputSchema is not valid JSON");
@@ -77,6 +86,12 @@ bool ParseOutputSchema(const nlohmann::json &json, std::string &output)
if (outputSchema.is_string()) {
output = outputSchema.get<std::string>();
if (!output.empty()) {
if (output.size() > MAX_SCHEMA_STRING_LENGTH) {
TAG_LOGE(AAFwkTag::CLI_TOOL,
"ParseFromJson failed: outputSchema too long: %{public}u, max: %{public}u",
static_cast<uint32_t>(output.size()), MAX_SCHEMA_STRING_LENGTH);
return false;
}
nlohmann::json parsed = nlohmann::json::parse(output, nullptr, false);
if (parsed.is_discarded()) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "ParseFromJson failed: outputSchema is not valid JSON");
@@ -100,14 +115,24 @@ bool ParseFunctionType(const nlohmann::json &json, FunctionType &output)
TAG_LOGE(AAFwkTag::CLI_TOOL, "Invalid functionType type in JSON, must be integer");
return false;
}
int32_t typeValue = functionType.get<int32_t>();
if (typeValue >= 0 && typeValue < static_cast<int32_t>(FunctionType::END)) {
output = static_cast<FunctionType>(typeValue);
if (functionType.is_number_unsigned()) {
auto val = functionType.get<nlohmann::json::number_unsigned_t>();
if (val >= static_cast<decltype(val)>(FunctionType::END)) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Invalid functionType value: %{public}llu, out of range [0, %{public}d)",
static_cast<unsigned long long>(val), static_cast<int32_t>(FunctionType::END));
return false;
}
output = static_cast<FunctionType>(val);
return true;
}
TAG_LOGE(AAFwkTag::CLI_TOOL, "Invalid functionType value: %{public}d, out of range [0, %{public}d)",
typeValue, static_cast<int32_t>(FunctionType::END));
return false;
auto val = functionType.get<nlohmann::json::number_integer_t>();
if (val < 0 || val >= static_cast<decltype(val)>(FunctionType::END)) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Invalid functionType value: %{public}lld, out of range [0, %{public}d)",
static_cast<long long>(val), static_cast<int32_t>(FunctionType::END));
return false;
}
output = static_cast<FunctionType>(val);
return true;
}
} // namespace
@@ -236,6 +261,11 @@ bool FunctionInfo::Validate(const FunctionInfo &function)
}
if (!function.inputSchema.empty()) {
if (function.inputSchema.size() > MAX_SCHEMA_STRING_LENGTH) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Validate failed: inputSchema too long: %{public}u, max: %{public}u",
static_cast<uint32_t>(function.inputSchema.size()), MAX_SCHEMA_STRING_LENGTH);
return false;
}
nlohmann::json inputSchemaJson = nlohmann::json::parse(function.inputSchema, nullptr, false);
if (inputSchemaJson.is_discarded()) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Validate failed: inputSchema is not valid JSON");
@@ -244,6 +274,11 @@ bool FunctionInfo::Validate(const FunctionInfo &function)
}
if (!function.outputSchema.empty()) {
if (function.outputSchema.size() > MAX_SCHEMA_STRING_LENGTH) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Validate failed: outputSchema too long: %{public}u, max: %{public}u",
static_cast<uint32_t>(function.outputSchema.size()), MAX_SCHEMA_STRING_LENGTH);
return false;
}
nlohmann::json outputSchemaJson = nlohmann::json::parse(function.outputSchema, nullptr, false);
if (outputSchemaJson.is_discarded()) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Validate failed: outputSchema is not valid JSON");
@@ -271,6 +306,10 @@ int32_t FunctionsRawData::RawDataCpy(const void *readdata)
TAG_LOGE(AAFwkTag::CLI_TOOL, "null data or zero size");
return ERR_INVALID_VALUE;
}
if (size > MAX_RAW_DATA_SIZE) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "raw data size too large: %{public}u, max: %{public}u", size, MAX_RAW_DATA_SIZE);
return ERR_INVALID_VALUE;
}
void* newData = malloc(size);
if (newData == nullptr) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "malloc failed");
@@ -290,8 +329,13 @@ int32_t FunctionsRawData::RawDataCpy(const void *readdata)
return ERR_OK;
}
void FunctionsRawData::FromFunctionInfoVec(const std::vector<FunctionInfo> &functions, FunctionsRawData &rawData)
int32_t FunctionsRawData::FromFunctionInfoVec(const std::vector<FunctionInfo> &functions, FunctionsRawData &rawData)
{
if (functions.size() > MAX_FUNCTION_INFO_COUNT) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "FromFunctionInfoVec exceed max count %{public}u, count: %{public}zu",
MAX_FUNCTION_INFO_COUNT, functions.size());
return ERR_INVALID_VALUE;
}
std::stringstream ss;
uint32_t count = functions.size();
ss.write(reinterpret_cast<const char*>(&count), sizeof(count));
@@ -307,16 +351,25 @@ void FunctionsRawData::FromFunctionInfoVec(const std::vector<FunctionInfo> &func
rawData.data = rawData.ownedData.data();
rawData.size = rawData.ownedData.size();
rawData.isMalloc = false;
return ERR_OK;
}
int32_t FunctionsRawData::ToFunctionInfoVec(const FunctionsRawData &rawData, std::vector<FunctionInfo> &functions)
{
if (rawData.data == nullptr || rawData.size == 0) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "ToFunctionInfoVec failed: null data or zero size");
return ERR_INVALID_VALUE;
}
std::stringstream ss;
ss.write(reinterpret_cast<const char *>(rawData.data), rawData.size);
ss.seekg(0, std::ios::beg);
uint32_t ssLength = static_cast<uint32_t>(ss.str().length());
uint32_t count = 0;
ss.read(reinterpret_cast<char *>(&count), sizeof(count));
if (!ReadRaw(ss, &count, sizeof(count))) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to read count, stream state invalid");
return ERR_INVALID_VALUE;
}
if (count > MAX_FUNCTION_INFO_COUNT) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "functions exceed maxSize %{public}d, count: %{public}d",
MAX_FUNCTION_INFO_COUNT, count);
@@ -324,22 +377,10 @@ int32_t FunctionsRawData::ToFunctionInfoVec(const FunctionsRawData &rawData, std
}
functions.resize(count);
for (uint32_t i = 0; i < count; ++i) {
uint32_t functionSize = 0;
ss.read(reinterpret_cast<char *>(&functionSize), sizeof(functionSize));
if (functionSize > ssLength - static_cast<uint32_t>(ss.tellg())) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "functionSize:%{public}u is invalid", functionSize);
return ERR_INVALID_VALUE;
}
std::string functionStr(functionSize, '\0');
ss.read(functionStr.data(), functionSize);
nlohmann::json j = nlohmann::json::parse(functionStr, nullptr, false);
if (j.is_discarded()) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to parse JSON for function %{public}d", i);
return ERR_JSON_PARSE_FAILED;
}
if (!FunctionInfo::ParseFromJson(j, functions[i])) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to parse FunctionInfo from JSON for function %{public}d", i);
return ERR_JSON_PARSE_FAILED;
int32_t ret = ReadOneItem<FunctionInfo>(ss, ssLength, functions[i], false, ERR_JSON_PARSE_FAILED);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "ReadOneItem failed, index: %{public}u, ret: %{public}d", i, ret);
return ret;
}
}
return ERR_OK;
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2026 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 "raw_data_utils.h"
#include <sstream>
#include <string>
#include <nlohmann/json.hpp>
#include "cli_error_code.h"
#include "hilog_tag_wrapper.h"
namespace OHOS {
namespace CliTool {
// Read a length-prefixed JSON item from the stream and parse it into out.
int32_t ReadItemToJson(std::stringstream &ss, uint32_t ssLength, bool allowComments,
int32_t parseFailCode, nlohmann::json &out)
{
uint32_t itemSize = 0;
if (!ReadRaw(ss, &itemSize, sizeof(itemSize))) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to read item size, stream state invalid");
return ERR_INVALID_VALUE;
}
std::streamoff curPos = ss.tellg();
std::streamoff total = static_cast<std::streamoff>(ssLength);
if (curPos < 0 || curPos > total || itemSize > total - curPos) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "itemSize:%{public}u is invalid", itemSize);
return ERR_INVALID_VALUE;
}
std::string itemStr(itemSize, '\0');
if (!ReadRaw(ss, itemStr.data(), itemSize)) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to read item data, stream state invalid");
return ERR_INVALID_VALUE;
}
out = nlohmann::json::parse(itemStr, nullptr, false, allowComments);
if (out.is_discarded()) {
TAG_LOGE(AAFwkTag::CLI_TOOL, "Failed to parse JSON");
return parseFailCode;
}
return ERR_OK;
}
} // namespace CliTool
} // namespace OHOS