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 PACKAGE_PREFIX = "@package:";
28 constexpr std::string_view NORMALIZED_LOCAL_PREFIX = "@normalized:N&&";
29 constexpr std::string_view NORMALIZED_OHM_DELIMITER = "&";
30 constexpr size_t FILEPATH_ITEM_MAX_PART_NUM = 2;
31
32 const std::vector<std::string_view> PATH_PREFIX_LIST = {BUNDLE_PREFIX, PACKAGE_PREFIX, NORMALIZED_LOCAL_PREFIX};
33
FindPrefix(const std::string & name,std::string & prefix)34 bool FindPrefix(const std::string &name, std::string &prefix)
35 {
36 return std::any_of(PATH_PREFIX_LIST.begin(), PATH_PREFIX_LIST.end(), [&](const std::string_view &elem) {
37 bool ret = panda::guard::StringUtil::IsPrefixMatched(name, elem.data());
38 if (ret) {
39 prefix = elem;
40 }
41 return ret;
42 });
43 }
44 } // namespace
45
Init()46 void panda::guard::ReferenceFilePath::Init()
47 {
48 std::string prefix;
49 if (FindPrefix(filePath_, prefix)) {
50 this->prefix_ = prefix;
51 this->rawName_ = filePath_.substr(prefix.size(), filePath_.size() - prefix.size());
52 this->DeterminePathType();
53 } else if (filePath_.find(COLON_DELIMITER) == std::string::npos) {
54 pathType_ = FilePathType::LOCAL_FILE_NO_PREFIX;
55 rawName_ = filePath_;
56 } else {
57 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
58 }
59
60 this->isRemoteFile_ = pathType_ == FilePathType::EXTERNAL_DEPENDENCE;
61 LOG(INFO, PANDAGUARD) << TAG << "file path: " << (int)pathType_ << " " << rawName_;
62 }
63
DeterminePathType()64 void panda::guard::ReferenceFilePath::DeterminePathType()
65 {
66 // here determines if this records need to be processed as external dependence, including the following three scene
67 auto it = program_->nodeTable_.find(rawName_);
68 std::string pkgName;
69 if (it != program_->nodeTable_.end()) {
70 pkgName = it->second.pkgName_;
71 } else {
72 /* scene 1: record that does not exist in abc, when HAP references the record in HSP, the corresponding file
73 * does not exist in abc */
74 auto itRaw = program_->prog_->record_table.find(rawName_);
75 if (itRaw == program_->prog_->record_table.end()) {
76 LOG(INFO, PANDAGUARD) << TAG << "not found record: " << rawName_;
77 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
78 return;
79 }
80
81 // scene 2: records that are not code files
82 if (!Node::FindPkgName(itRaw->second, pkgName) && !Node::IsJsonFile(itRaw->second)) {
83 LOG(INFO, PANDAGUARD) << TAG << "invalid record: " << rawName_;
84 pathType_ = FilePathType::EXTERNAL_DEPENDENCE;
85 return;
86 }
87 }
88
89 // scene 3: records whose package names are in the skip list
90 if (GuardContext::GetInstance()->GetGuardOptions()->IsSkippedRemoteHar(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