Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions packing_tool/frameworks/include/parse_packing_int.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* 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 DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_PARSE_PACKING_INT_H
#define DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_PARSE_PACKING_INT_H

#include <charconv>
#include <cstdint>
#include <string>
#include <string_view>
#include <system_error>

namespace OHOS {
namespace AppPackingTool {
/*
* Parse a whole-token decimal int32 from packing-tool CLI / config text.
* Reject empty, overflow, underflow, leading/trailing junk, '+', hex, and floats.
* Valid in-range values keep the same numeric result as std::stoi on digit-only input.
*/
inline bool ParsePackingInt32(std::string_view text, int32_t &out)
{
if (text.empty()) {
return false;
}
int32_t value = 0;
auto result = std::from_chars(text.data(), text.data() + text.size(), value);
if (result.ec != std::errc() || result.ptr != text.data() + text.size()) {
return false;
}
out = value;
return true;
}

inline bool ParsePackingInt32(const std::string &text, int32_t &out)
{
return ParsePackingInt32(std::string_view(text), out);
}

inline bool ParsePackingInt32(const char *text, int32_t &out)
{
if (text == nullptr) {
return false;
}
return ParsePackingInt32(std::string_view(text), out);
}
} // namespace AppPackingTool
} // namespace OHOS

#endif // DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_PARSE_PACKING_INT_H
121 changes: 37 additions & 84 deletions packing_tool/frameworks/src/general_normalize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "json/pack_info.h"
#include "log.h"
#include "utils.h"
#include "parse_packing_int.h"
#include "zip_utils.h"
#include "error/packing_tool_err_msg.h"

Expand Down Expand Up @@ -96,16 +97,10 @@ int32_t GeneralNormalize::PreProcess()
"--version-code is invalid.").c_str());
return ERR_INVALID_VALUE;
}
try {
int32_t versionCode = std::stoi(it->second);
if (versionCode > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
"--version-code is invalid.").c_str());
return ERR_INVALID_VALUE;
}
} catch (const std::exception& e) {
int32_t versionCode = 0;
if (!ParsePackingInt32(it->second, versionCode) || versionCode > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"--version-code is invalid.").c_str());
return ERR_INVALID_VALUE;
}
}
Expand Down Expand Up @@ -155,16 +150,10 @@ int32_t GeneralNormalize::PreProcess()
"--min-compatible-version-code is invalid.").c_str());
return ERR_INVALID_VALUE;
}
try {
int32_t minCompatibleVersionCode = std::stoi(it->second);
if (minCompatibleVersionCode > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
"--min-compatible-version-code is invalid.").c_str());
return ERR_INVALID_VALUE;
}
} catch (const std::exception& e) {
int32_t minCompatibleVersionCode = 0;
if (!ParsePackingInt32(it->second, minCompatibleVersionCode) || minCompatibleVersionCode > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"--min-compatible-version-code is invalid.").c_str());
return ERR_INVALID_VALUE;
}
}
Expand All @@ -176,16 +165,10 @@ int32_t GeneralNormalize::PreProcess()
"--min-api-version is invalid.").c_str());
return ERR_INVALID_VALUE;
}
try {
int32_t minApiVersion = std::stoi(it->second);
if (minApiVersion > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
"--min-api-version is invalid.").c_str());
return ERR_INVALID_VALUE;
}
} catch (const std::exception& e) {
int32_t minApiVersion = 0;
if (!ParsePackingInt32(it->second, minApiVersion) || minApiVersion > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"--min-api-version is invalid.").c_str());
return ERR_INVALID_VALUE;
}
}
Expand All @@ -197,16 +180,10 @@ int32_t GeneralNormalize::PreProcess()
"--target-api-version is invalid.").c_str());
return ERR_INVALID_VALUE;
}
try {
int32_t targetApiVersion = std::stoi(it->second);
if (targetApiVersion > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
"--target-api-version is invalid.").c_str());
return ERR_INVALID_VALUE;
}
} catch (const std::exception& e) {
int32_t targetApiVersion = 0;
if (!ParsePackingInt32(it->second, targetApiVersion) || targetApiVersion > Constants::MAX_VERSION_CODE) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"--target-api-version is invalid.").c_str());
return ERR_INVALID_VALUE;
}
}
Expand Down Expand Up @@ -270,11 +247,9 @@ bool GeneralNormalize::ModifyModuleJson(const std::string &moduleJsonPath,
moduleJson.GetStageVersion(version);
generalNormalizeVersion.originVersionCode = version.versionCode;
int32_t versionCode = 0;
try {
versionCode = std::stoi(parameterMap_.at(Constants::PARAM_VERSION_CODE));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_VERSION_CODE), versionCode)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!moduleJson.SetVersionCode(versionCode, true)) {
Expand Down Expand Up @@ -327,11 +302,9 @@ bool GeneralNormalize::ModifyModuleJson(const std::string &moduleJsonPath,
moduleJson.GetStageVersion(version);
generalNormalizeVersion.originMinCompatibleVersionCode = version.minCompatibleVersionCode;
int32_t minCompatibleVersionCode = 0;
try {
minCompatibleVersionCode = std::stoi(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE), minCompatibleVersionCode)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!moduleJson.SetMinCompatibleVersionCode(minCompatibleVersionCode, true)) {
Expand All @@ -347,11 +320,9 @@ bool GeneralNormalize::ModifyModuleJson(const std::string &moduleJsonPath,
moduleJson.GetMinApiVersion(originMinAPIVersion);
generalNormalizeVersion.originMinAPIVersion = originMinAPIVersion;
int32_t minAPIVersion = 0;
try {
minAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_MIN_API_VERSION));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_MIN_API_VERSION), minAPIVersion)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!moduleJson.SetMinAPIVersion(minAPIVersion, true)) {
Expand All @@ -367,11 +338,9 @@ bool GeneralNormalize::ModifyModuleJson(const std::string &moduleJsonPath,
moduleJson.GetTargetApiVersion(originTargetAPIVersion);
generalNormalizeVersion.originTargetAPIVersion = originTargetAPIVersion;
int32_t targetAPIVersion = 0;
try {
targetAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION), targetAPIVersion)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!moduleJson.SetTargetAPIVersion(targetAPIVersion, true)) {
Expand Down Expand Up @@ -473,11 +442,9 @@ bool GeneralNormalize::ModifyConfigJson(const std::string &configJsonPath,
configJson.GetFaVersion(version);
generalNormalizeVersion.originVersionCode = version.versionCode;
int32_t versionCode = 0;
try {
versionCode = std::stoi(parameterMap_.at(Constants::PARAM_VERSION_CODE));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_VERSION_CODE), versionCode)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!configJson.SetVersionCode(versionCode, false)) {
Expand Down Expand Up @@ -517,11 +484,9 @@ bool GeneralNormalize::ModifyConfigJson(const std::string &configJsonPath,
configJson.GetFaVersion(version);
generalNormalizeVersion.originMinCompatibleVersionCode = version.minCompatibleVersionCode;
int32_t minCompatibleVersionCode = 0;
try {
minCompatibleVersionCode = std::stoi(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE), minCompatibleVersionCode)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!configJson.SetMinCompatibleVersionCode(minCompatibleVersionCode, false)) {
Expand All @@ -537,11 +502,9 @@ bool GeneralNormalize::ModifyConfigJson(const std::string &configJsonPath,
configJson.GetFaModuleApiVersion(moduleApiVersion);
generalNormalizeVersion.originMinAPIVersion = moduleApiVersion.compatibleApiVersion;
int32_t minAPIVersion = 0;
try {
minAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_MIN_API_VERSION));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_MIN_API_VERSION), minAPIVersion)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!configJson.SetMinAPIVersion(minAPIVersion, false)) {
Expand All @@ -557,11 +520,9 @@ bool GeneralNormalize::ModifyConfigJson(const std::string &configJsonPath,
configJson.GetFaModuleApiVersion(moduleApiVersion);
generalNormalizeVersion.originTargetAPIVersion = moduleApiVersion.targetApiVersion;
int32_t targetAPIVersion = 0;
try {
targetAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION), targetAPIVersion)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!configJson.SetTargetAPIVersion(targetAPIVersion, false)) {
Expand Down Expand Up @@ -660,11 +621,9 @@ bool GeneralNormalize::ModifyPackInfo(const std::string &packInfoPath)
auto it = parameterMap_.find(Constants::PARAM_VERSION_CODE);
if (it != parameterMap_.end()) {
int32_t versionCode = 0;
try {
versionCode = std::stoi(parameterMap_.at(Constants::PARAM_VERSION_CODE));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_VERSION_CODE), versionCode)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!packInfo.SetVersionCode(versionCode)) {
Expand Down Expand Up @@ -707,11 +666,9 @@ bool GeneralNormalize::ModifyPackInfo(const std::string &packInfoPath)
it = parameterMap_.find(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE);
if (it != parameterMap_.end()) {
int32_t minCompatibleVersionCode = 0;
try {
minCompatibleVersionCode = std::stoi(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE), minCompatibleVersionCode)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!packInfo.SetMinCompatibleVersionCode(minCompatibleVersionCode)) {
Expand All @@ -724,11 +681,9 @@ bool GeneralNormalize::ModifyPackInfo(const std::string &packInfoPath)
it = parameterMap_.find(Constants::PARAM_MIN_API_VERSION);
if (it != parameterMap_.end()) {
int32_t minAPIVersion = 0;
try {
minAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_MIN_API_VERSION));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_MIN_API_VERSION), minAPIVersion)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!packInfo.SetMinAPIVersion(minAPIVersion)) {
Expand All @@ -741,11 +696,9 @@ bool GeneralNormalize::ModifyPackInfo(const std::string &packInfoPath)
it = parameterMap_.find(Constants::PARAM_TARGET_API_VERSION);
if (it != parameterMap_.end()) {
int32_t targetAPIVersion = 0;
try {
targetAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION));
} catch (const std::exception& e) {
if (!ParsePackingInt32(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION), targetAPIVersion)) {
LOGE("%s", PackingToolErrMsg::GENERAL_NORMALIZE_MODE_ARGS_INVALID.toStringWithArgs(
("Exception: " + std::string(e.what())).c_str()).c_str());
"CLI integer parameter is invalid.").c_str());
return false;
}
if (!packInfo.SetTargetAPIVersion(targetAPIVersion)) {
Expand Down
20 changes: 6 additions & 14 deletions packing_tool/frameworks/src/packager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "log.h"
#include "scan_statdulpicate.h"
#include "utils.h"
#include "parse_packing_int.h"
#include "zip_utils.h"
#include "error/packing_tool_err_msg.h"
using packing_tool::error::PackingToolErrMsg;
Expand Down Expand Up @@ -176,14 +177,9 @@ bool Packager::IsCompressLevelValid()
"--compress-level value not number between 1-9.").c_str());
return false;
}
try {
int level = std::stoi(levelStr);
if (level < Constants::MIN_COMPRESS_LEVEL || level > Constants::MAX_COMPRESS_LEVEL) {
LOGE("%s", PackingToolErrMsg::COMMAND_PARSER_FAILED.toStringWithArgs(
"--compress-level value not number between 1-9.").c_str());
return false;
}
} catch (const std::exception& e) {
int32_t level = 0;
if (!ParsePackingInt32(levelStr, level) ||
level < Constants::MIN_COMPRESS_LEVEL || level > Constants::MAX_COMPRESS_LEVEL) {
LOGE("%s", PackingToolErrMsg::COMMAND_PARSER_FAILED.toStringWithArgs(
"--compress-level value not number between 1-9.").c_str());
return false;
Expand Down Expand Up @@ -613,9 +609,7 @@ bool Packager::ParseAtomicServiceEntrySizeLimitParameter()
auto it = parameterMap_.find(Constants::PARAM_ATOMIC_SERVICE_ENTRY_SIZE_LIMIT);
int32_t entrySizeLimit = Constants::ATOMIC_SERVICE_ENTRY_SIZE_LIMIT_DEFAULT;
if (it != parameterMap_.end()) {
try {
entrySizeLimit = std::stoi(it->second);
} catch (const std::exception& e) {
if (!ParsePackingInt32(it->second, entrySizeLimit)) {
LOGE("%s", PackingToolErrMsg::PARSE_ATOMIC_SERVICE_SIZE_LIMIT_FAILED.toStringWithArgs(
std::vector<std::string>{
"parseAtomicServiceEntrySizeLimitParameter failed, "
Expand Down Expand Up @@ -643,9 +637,7 @@ bool Packager::ParseAtomicServiceNonEntrySizeLimitParameter()
auto it = parameterMap_.find(Constants::PARAM_ATOMIC_SERVICE_NON_ENTRY_SIZE_LIMIT);
int32_t nonEntrySizeLimit = Constants::ATOMIC_SERVICE_NON_ENTRY_SIZE_LIMIT_DEFAULT;
if (it != parameterMap_.end()) {
try {
nonEntrySizeLimit = std::stoi(it->second);
} catch (const std::exception& e) {
if (!ParsePackingInt32(it->second, nonEntrySizeLimit)) {
LOGE("%s", PackingToolErrMsg::PARSE_ATOMIC_SERVICE_SIZE_LIMIT_FAILED.toStringWithArgs(
std::vector<std::string>{
"parseAtomicServiceSizeLimit failed, "
Expand Down
12 changes: 6 additions & 6 deletions packing_tool/frameworks/src/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include "utils.h"

#include "parse_packing_int.h"

#include <algorithm>
#include <cmath>
#include <cctype>
Expand Down Expand Up @@ -361,19 +363,17 @@ bool Utils::IsPositiveInteger(const std::string& str, int min, int max)
return false;
}
for (char c : str) {
if (!std::isdigit(c)) {
if (!std::isdigit(static_cast<unsigned char>(c))) {
return false;
}
}
try {
int number = std::stoi(str);
return number >= min && number <= max;
} catch (const std::out_of_range& e) {
int32_t number = 0;
if (!ParsePackingInt32(str, number)) {
LOGE("%s", PackingToolErrMsg::COMMAND_PARSER_FAILED.toStringWithArgs(
("Number " + str + " is Out of Range!").c_str()).c_str());
return false;
}
return true;
return number >= min && number <= max;
}

bool Utils::StringToBool(const std::string& str)
Expand Down
Loading