针对png资源图片进行校验

Signed-off-by: fangyunzhong <fangyunzhong2@huawei.com>
This commit is contained in:
fangyunzhong
2023-07-10 09:35:26 +00:00
parent bd07eefc8f
commit de7fd9f728
13 changed files with 320 additions and 10 deletions
+2
View File
@@ -37,6 +37,7 @@ ohos_executable("restool") {
"src/preview_manager.cpp",
"src/reference_parser.cpp",
"src/resource_append.cpp",
"src/resource_check.cpp",
"src/resource_directory.cpp",
"src/resource_item.cpp",
"src/resource_merge.cpp",
@@ -66,6 +67,7 @@ ohos_executable("restool") {
"build/bounds_checking_function:restool_bounds_checking_function",
"build/jsoncpp:restool_jsoncpp",
"build/sqlite3:restool_sqlite",
"//third_party/libpng:libpng_static",
"//third_party/libxml2:static_libxml2",
]
+2 -1
View File
@@ -23,7 +23,8 @@
"bounds_checking_function",
"libxml2",
"jsoncpp",
"sqlite"
"sqlite",
"libpng"
]
},
"build": {
+8 -1
View File
@@ -16,7 +16,8 @@
#ifndef OHOS_RESTOOL_CONFIG_PARSER_H
#define OHOS_RESTOOL_CONFIG_PARSER_H
#include<functional>
#include <functional>
#include <set>
#include "resource_util.h"
namespace OHOS {
@@ -45,6 +46,10 @@ public:
ModuleType GetModuleType() const;
uint32_t ParseRefence();
uint32_t Save(const std::string &filePath) const;
const std::map<std::string, std::set<uint32_t>> GetCheckNode() const
{
return jsonCheckIds_;
}
void SetDependEntry(const bool isDenpend)
{
dependEntry = isDenpend;
@@ -75,6 +80,7 @@ private:
bool GetRefIdFromString(std::string &value, bool &update, const std::string &match) const;
bool ParseModuleType(const std::string &type);
bool ParseAbilitiesForDepend(Json::Value &moduleNode);
void AddCheckNode(const std::string &key, uint32_t id);
std::string filePath_;
std::string packageName_;
std::string moduleName_;
@@ -83,6 +89,7 @@ private:
std::string mainAbility_;
int32_t abilityIconId_;
int32_t abilityLabelId_;
std::map<std::string, std::set<uint32_t>> jsonCheckIds_;
static const std::map<std::string, ModuleType> MODULE_TYPES;
static const std::map<std::string, std::string> JSON_STRING_IDS;
static const std::map<std::string, std::string> JSON_ARRAY_IDS;
+4
View File
@@ -30,6 +30,10 @@ public:
virtual ~ResourceAppend() {};
uint32_t Append();
uint32_t Combine();
const std::map<int32_t, std::vector<std::shared_ptr<ResourceItem>>> GetItems() const
{
return items_;
}
private:
bool Combine(const std::string &folderPath);
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2023 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_RESTOOL_RESOURCE_CHECK_H
#define OHOS_RESTOOL_RESOURCE_CHECK_H
#include "config_parser.h"
#include "resource_append.h"
#include "resource_item.h"
#include <iostream>
#include <stdint.h>
#include <map>
#include <set>
namespace OHOS {
namespace Global {
namespace Restool {
class ResourceCheck {
public:
ResourceCheck(const ConfigParser &configJson, const std::shared_ptr<ResourceAppend> &resourceAppend = nullptr);
virtual ~ResourceCheck() {};
void CheckConfigJson();
void CheckConfigJsonForCombine();
private:
const ConfigParser configJson_;
const std::shared_ptr<ResourceAppend> resourceAppend_;
void CheckNodeInResourceItem(const std::string &key, const ResourceItem &resourceItem);
bool GetPngWidthAndHeight(const std::string &filePath, uint32_t *width, uint32_t *height);
bool IsValidPngImage(FILE *&in) const;
void CloseFile(FILE *fp);
};
}
}
}
#endif
+25 -4
View File
@@ -16,9 +16,10 @@
#ifndef OHOS_RESTOOL_RESOURCE_DATA_H
#define OHOS_RESTOOL_RESOURCE_DATA_H
#include<map>
#include<stdint.h>
#include<string>
#include <map>
#include <stdint.h>
#include <string>
#include <vector>
namespace OHOS {
namespace Global {
@@ -38,7 +39,7 @@ const static std::string LONG_PATH_HEAD = "\\\\?\\";
const static std::string ID_DEFINED_INDENTATION = " ";
const static int32_t VERSION_MAX_LEN = 128;
const static int32_t INT_TO_BYTES = sizeof(uint32_t);
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 4.003" };
static const int8_t RESTOOL_VERSION[VERSION_MAX_LEN] = { "Restool 4.004" };
const static int32_t TAG_LEN = 4;
enum class KeyType {
@@ -216,6 +217,26 @@ const std::map<int32_t, ResType> g_resTypeMap = {
{ static_cast<int32_t>(ResType::INVALID_RES_TYPE), ResType::INVALID_RES_TYPE},
};
const std::map<std::string, std::vector<uint32_t>> g_normalIconMap = {
{ "sdpi-phone", {41, 144} },
{ "sdpi-tablet", {51, 192} },
{ "mdpi-phone", {54, 192} },
{ "mdpi-tablet", {68, 256} },
{ "ldpi-phone", {81, 288} },
{ "ldpi-tablet", {102, 384} },
{ "xldpi-phone", {108, 384} },
{ "xldpi-tablet", {136, 512} },
{ "xxldpi-phone", {162, 576} },
{ "xxldpi-tablet", {204, 768} },
{ "xxxldpi-phone", {216, 768} },
{ "xxxldpi-tablet", {272, 1024} },
};
const std::map<std::string, uint32_t> g_keyNodeIndexs = {
{ "icon", 0 },
{ "startWindowIcon", 1 },
};
struct DirectoryInfo {
std::string limitKey;
std::string fileCluster;
+3
View File
@@ -21,6 +21,7 @@
#include "resource_util.h"
#include "resource_item.h"
#include "resource_data.h"
#include "resource_append.h"
namespace OHOS {
namespace Global {
@@ -55,6 +56,8 @@ private:
uint32_t HandleLabel(std::vector<ResourceItem> &items, ConfigParser &config) const;
uint32_t HandleIcon(std::vector<ResourceItem> &items, ConfigParser &config) const;
void SaveResourceItem(const ResourceItem &resourceItem, int32_t nextId) const;
void CheckConfigJson();
void CheckConfigJsonForCombine(ResourceAppend &resourceAppend);
bool CopyIcon(std::string &dataPath, const std::string &idName, std::string &fileName) const;
PackageParser packageParser_;
std::string moduleName_;
+8
View File
@@ -208,6 +208,14 @@ public:
*/
static FileEntry::FilePath GetMainPath(const std::string input);
/**
* @brief Gets the standard size of icons under different qualifier phrases
* @param keyParams set of qualifiers
* @param uint32_t index
* @return standard size of the png
*/
static uint32_t GetNormalSize(const std::vector<KeyParam> &keyParams, uint32_t index);
private:
enum class IgnoreType {
IGNORE_FILE,
+17 -2
View File
@@ -14,8 +14,8 @@
*/
#include "config_parser.h"
#include<iostream>
#include<regex>
#include <iostream>
#include <regex>
#include "reference_parser.h"
#include "restool_errors.h"
@@ -370,10 +370,25 @@ bool ConfigParser::ParseJsonStringRef(Json::Value &parent, const string &key, Js
}
if (update) {
parent[key + "Id"] = atoi(value.c_str());
AddCheckNode(key, static_cast<uint32_t>(atoi(value.c_str())));
}
return true;
}
void ConfigParser::AddCheckNode(const string &key, uint32_t id)
{
if (g_keyNodeIndexs.find(key) != g_keyNodeIndexs.end()) {
auto result = jsonCheckIds_.find(key);
if (result == jsonCheckIds_.end()) {
set<uint32_t> set;
set.emplace(id);
jsonCheckIds_.emplace(key, set);
} else {
result->second.emplace(id);
}
}
}
bool ConfigParser::GetRefIdFromString(string &value, bool &update, const string &match) const
{
ReferenceParser refParser;
+1 -1
View File
@@ -24,7 +24,7 @@ namespace Global {
namespace Restool {
using namespace std;
const std::string Header::LICENSE_HEADER = "/*\n\
* Copyright (c) 2021 Huawei Device Co., Ltd.\n\
* Copyright (c) 2023 Huawei Device Co., Ltd.\n\
* Licensed under the Apache License, Version 2.0 (the \"License\");\n\
* you may not use this file except in compliance with the License.\n\
* You may obtain a copy of the License at\n\
+151
View File
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2023 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 "resource_check.h"
#include "file_manager.h"
#include <png.h>
namespace OHOS {
namespace Global {
namespace Restool {
using namespace std;
namespace {
constexpr int PNG_BYTRS_TO_CHECK = 8;
}
ResourceCheck::ResourceCheck(const ConfigParser &configJson, const shared_ptr<ResourceAppend> &resourceAppend)
: configJson_(configJson), resourceAppend_(resourceAppend)
{
}
void ResourceCheck::CheckConfigJson()
{
const map<string, set<uint32_t>> jsonCheckIds = configJson_.GetCheckNode();
auto &fileManager = FileManager::GetInstance();
auto &allResource = fileManager.GetResources();
for (auto it = jsonCheckIds.begin(); it != jsonCheckIds.end(); it++) {
for (const auto &id : it->second) {
auto res = allResource.find(id);
if (res == allResource.end()) {
continue;
}
for (auto resourceItem : res->second) {
CheckNodeInResourceItem(it->first, resourceItem);
}
}
}
}
void ResourceCheck::CheckConfigJsonForCombine()
{
const map<string, set<uint32_t>> jsonCheckIds = configJson_.GetCheckNode();
auto &allResource = resourceAppend_->GetItems();
for (auto it = jsonCheckIds.begin(); it != jsonCheckIds.end(); it++) {
for (const auto &id : it->second) {
auto res = allResource.find(id);
if (res == allResource.end()) {
continue;
}
for (auto resourceItemPtr : res->second) {
CheckNodeInResourceItem(it->first, *resourceItemPtr);
}
}
}
}
void ResourceCheck::CheckNodeInResourceItem(const string &key, const ResourceItem &resourceItem)
{
string limitKey = resourceItem.GetLimitKey();
string filePath = resourceItem.GetFilePath();
uint32_t width;
uint32_t height;
if (!GetPngWidthAndHeight(filePath, &width, &height)) {
return;
}
if (width != height) {
cout << "Warning: the png width and height not equal" << NEW_LINE_PATH << filePath << endl;
return;
}
auto result = g_keyNodeIndexs.find(key);
if (result == g_keyNodeIndexs.end()) {
return;
}
uint32_t normalSize = ResourceUtil::GetNormalSize(resourceItem.GetKeyParam(), result->second);
if (normalSize != 0 && width > normalSize) {
string warningMsg = "Warning: The width or height of the png file referenced by the " + key + \
" exceeds the limit (" + to_string(normalSize) + " pixels)" + NEW_LINE_PATH + filePath;
cout << warningMsg << endl;
}
}
bool ResourceCheck::IsValidPngImage(FILE *&in) const
{
char checkheader[PNG_BYTRS_TO_CHECK];
if (fread(checkheader, 1, PNG_BYTRS_TO_CHECK, in) != PNG_BYTRS_TO_CHECK) {
return false;
}
if (png_sig_cmp(reinterpret_cast<png_const_bytep>(checkheader), 0, PNG_BYTRS_TO_CHECK) != 0) {
return false;
}
rewind(in);
return true;
}
bool ResourceCheck::GetPngWidthAndHeight(const string &filePath, uint32_t *width, uint32_t *height)
{
FILE *in = fopen(filePath.c_str(), "rb");
if (in == nullptr) {
cout << "Warning: " << filePath << " can not open" << endl;
return false;
}
if (!IsValidPngImage(in)) {
cout << "Warning: " << filePath << " is not png format" << endl;
CloseFile(in);
return false;
}
png_structp pngHandle = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (pngHandle == nullptr) {
CloseFile(in);
return false;
}
png_infop infoHandle = png_create_info_struct(pngHandle);
if (infoHandle == nullptr) {
CloseFile(in);
png_destroy_read_struct(&pngHandle, nullptr, nullptr);
return false;
}
png_init_io(pngHandle, in);
png_read_info(pngHandle, infoHandle);
unsigned int w;
unsigned int h;
png_get_IHDR(pngHandle, infoHandle, &w, &h, nullptr, nullptr, nullptr, nullptr, nullptr);
*width = w;
*height = h;
CloseFile(in);
png_destroy_read_struct(&pngHandle, &infoHandle, 0);
return true;
}
void ResourceCheck::CloseFile(FILE *fp)
{
if (fp != nullptr) {
fclose(fp);
}
}
}
}
}
+18 -1
View File
@@ -22,7 +22,7 @@
#include "increment_manager.h"
#include "resource_merge.h"
#include "resource_table.h"
#include "resource_append.h"
#include "resource_check.h"
#include "preview_manager.h"
namespace OHOS {
@@ -315,6 +315,12 @@ uint32_t ResourcePack::GenerateConfigJson()
return configJson_.Save(outputPath);
}
void ResourcePack::CheckConfigJson()
{
ResourceCheck resourceCheck(configJson_);
resourceCheck.CheckConfigJson();
}
uint32_t ResourcePack::ScanResources(const vector<string> &inputs, const string &output)
{
auto &fileManager = FileManager::GetInstance();
@@ -364,6 +370,8 @@ uint32_t ResourcePack::PackNormal()
return RESTOOL_ERROR;
}
CheckConfigJson();
ResourceTable resourceTable;
if (!packageParser_.GetDependEntry().empty()) {
if (HandleFeature() != RESTOOL_SUCCESS) {
@@ -588,11 +596,20 @@ uint32_t ResourcePack::PackCombine()
return RESTOOL_ERROR;
}
CheckConfigJsonForCombine(resourceAppend);
if (GenerateHeader() != RESTOOL_SUCCESS) {
return RESTOOL_ERROR;
}
return RESTOOL_SUCCESS;
}
void ResourcePack::CheckConfigJsonForCombine(ResourceAppend &resourceAppend)
{
ResourceCheck resourceCheck(configJson_, make_shared<ResourceAppend>(resourceAppend));
resourceCheck.CheckConfigJsonForCombine();
}
}
}
}
+31
View File
@@ -402,6 +402,37 @@ FileEntry::FilePath ResourceUtil::GetMainPath(const string input)
return FileEntry::FilePath(input).GetParent();
}
uint32_t ResourceUtil::GetNormalSize(const vector<KeyParam> &keyParams, uint32_t index)
{
string device;
string dpi;
if (keyParams.size() == 0) {
device = "phone";
dpi = "sdpi";
}
for (const auto &keyparam : keyParams) {
string limitKey = GetKeyParamValue(keyparam);
if (limitKey.empty()) {
continue;
}
if (keyparam.keyType == KeyType::DEVICETYPE) {
device = limitKey;
} else if (keyparam.keyType == KeyType::RESOLUTION) {
dpi = limitKey;
}
}
if (device.empty()) {
device = "phone";
}
if (dpi.empty()) {
dpi = "sdpi";
}
if (device != "phone" && device != "tablet") {
return 0;
}
return g_normalIconMap.find(dpi + "-" + device)->second[index];
}
}
}
}