• 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 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