• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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