1 /**
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "file_path.h"
17
18 #include "configs/guard_context.h"
19 #include "program.h"
20 #include "util/assert_util.h"
21 #include "util/string_util.h"
22
23 namespace {
24 constexpr std::string_view TAG = "[FilePath]";
25 constexpr std::string_view COLON_DELIMITER = ":";
26 constexpr std::string_view BUNDLE_PREFIX = "@bundle:";
27 constexpr std::string_view NORMALIZED_LOCAL_PREFIX = "@normalized:N&&";
28 constexpr std::string_view NORMALIZED_OHM_DELIMITER = "&";
29 constexpr size_t FILEPATH_ITEM_MAX_PART_NUM = 2;
30
31 const std::vector<std::string_view> PATH_PREFIX_LIST = {BUNDLE_PREFIX, NORMALIZED_LOCAL_PREFIX};
32
FindPrefix(const std::string & name,std::string & prefix)33 bool FindPrefix(const std::string &name, std::string &prefix)
34 {
35 return std::any_of(PATH_PREFIX_LIST.begin(), PATH_PREFIX_LIST.end(), [&](const std::string_view &elem) {
36 bool ret = panda::guard::StringUtil::IsPrefixMatched(name, elem.data());
37 if (ret) {
38 prefix = elem;
39 }
40 return ret;
41 });
42 }
43 } // namespace
44
Init()45 void panda::guard::ReferenceFilePath::Init()
46 {
47 std::string prefix;
48 if (FindPrefix(filePath_, prefix)) {
49 this->prefix_ = prefix;
50 this->rawName_ = filePath_.substr(prefix.size(), filePath_.size() - prefix.size());
51 this->DeterminePathType();
52 } else if (filePath_.find(COLON_DELIMITER) == std::string::npos) {
53 pathType_ = FilePathType::LOCAL_FILE_NO_PREFIX;
54 rawName_ = filePath_;
55 } else {
56 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
57 }
58
59 this->isRemoteFile_ = pathType_ == FilePathType::EXTERNAL_DEPENDENCE;
60 LOG(INFO, PANDAGUARD) << TAG << "file path: " << (int)pathType_ << " " << rawName_;
61 }
62
DeterminePathType()63 void panda::guard::ReferenceFilePath::DeterminePathType()
64 {
65 // here determines if this records need to be processed as external dependence, including the following three scene
66 auto it = program_->nodeTable_.find(rawName_);
67 std::string pkgName;
68 if (it != program_->nodeTable_.end()) {
69 pkgName = it->second->pkgName_;
70 } else {
71 /* scene 1: record that does not exist in abc, when HAP references the record in HSP, the corresponding file
72 * does not exist in abc */
73 const auto itRaw = program_->prog_->record_table.find(rawName_);
74 if (itRaw == program_->prog_->record_table.end()) {
75 LOG(INFO, PANDAGUARD) << TAG << "not found record: " << rawName_;
76 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
77 return;
78 }
79
80 // scene 2: records that are not code files
81 if (!Node::FindPkgName(itRaw->second, pkgName) && !Node::IsJsonFile(itRaw->second)) {
82 LOG(INFO, PANDAGUARD) << TAG << "invalid record: " << rawName_;
83 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
84 return;
85 }
86 }
87
88 // scene 3: records whose package names are in the skip list or in remote har pkg list
89 const auto &options = GuardContext::GetInstance()->GetGuardOptions();
90 if (options->IsSkippedRemoteHar(pkgName) || options->IsReservedRemoteHarPkgNames(pkgName)) {
91 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
92 return;
93 }
94
95 this->pathType_ = FilePathType::LOCAL_FILE_WITH_PREFIX;
96 }
97
UpdateObfFilePath()98 void panda::guard::ReferenceFilePath::UpdateObfFilePath()
99 {
100 PANDA_GUARD_ASSERT_PRINT(!StringUtil::IsPrefixMatched(filePath_, prefix_), TAG, ErrorCode::GENERIC_ERROR,
101 "prefix mismatched");
102 auto it = program_->nodeTable_.find(rawName_);
103 if (it == program_->nodeTable_.end()) {
104 LOG(INFO, PANDAGUARD) << TAG << "not found record: " << rawName_;
105 obfFilePath_ = filePath_;
106 } else {
107 obfFilePath_ = prefix_ + it->second->obfName_;
108 }
109 }
110
GetRawPath() const111 std::string panda::guard::ReferenceFilePath::GetRawPath() const
112 {
113 if (prefix_.empty() || prefix_ != NORMALIZED_LOCAL_PREFIX.data()) {
114 return rawName_;
115 }
116
117 auto parts = StringUtil::StrictSplit(rawName_, NORMALIZED_OHM_DELIMITER.data());
118 PANDA_GUARD_ASSERT_PRINT(parts.size() < FILEPATH_ITEM_MAX_PART_NUM, TAG, ErrorCode::GENERIC_ERROR,
119 "unexpected FilePathItem");
120 return parts[1];
121 }
122
SetFilePath(const std::string & filePath)123 void panda::guard::ReferenceFilePath::SetFilePath(const std::string &filePath)
124 {
125 filePath_ = filePath;
126 obfFilePath_ = filePath;
127 }
128
Update()129 void panda::guard::ReferenceFilePath::Update()
130 {
131 switch (pathType_) {
132 case FilePathType::LOCAL_FILE_NO_PREFIX: {
133 obfFilePath_ = GuardContext::GetInstance()->GetNameMapping()->GetFilePath(filePath_, false);
134 break;
135 }
136 case FilePathType::LOCAL_FILE_WITH_PREFIX: {
137 UpdateObfFilePath();
138 break;
139 }
140 case FilePathType::EXTERNAL_DEPENDENCE: {
141 return;
142 }
143 }
144 }
145