• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #define LOG_TAG "Utils"
16 
17 #include "utils.h"
18 
19 #include <string>
20 
21 #include "log_print.h"
22 #include "string_ex.h"
23 #include "uri.h"
24 #include "utils/anonymous.h"
25 
26 namespace OHOS::DataShare {
27 // Size of the characters that need to be left for both head and tail.
28 constexpr int32_t REVEAL_SIZE = 4;
29 constexpr const char *REPLACE_CHAIN = "***";
30 constexpr const char *DEFAULT_ANONYMOUS = "******";
GetInfoFromURI(const std::string & uri,UriInfo & uriInfo)31 bool URIUtils::GetInfoFromURI(const std::string &uri, UriInfo &uriInfo)
32 {
33     Uri uriTemp(uri);
34     std::vector<std::string> splitUri;
35     SplitStr(uriTemp.GetPath(), "/", splitUri);
36     if (splitUri.size() < PARAM_SIZE) {
37         return false;
38     }
39 
40     if (splitUri[BUNDLE_NAME].empty() || splitUri[MODULE_NAME].empty() ||
41         splitUri[STORE_NAME].empty() || splitUri[TABLE_NAME].empty()) {
42         ZLOGE("Uri has empty field! bundleName: %{public}s  uri: %{public}s", splitUri[BUNDLE_NAME].c_str(),
43             URIUtils::Anonymous(uri).c_str());
44         return false;
45     }
46 
47     uriInfo.bundleName = splitUri[BUNDLE_NAME];
48     uriInfo.moduleName = splitUri[MODULE_NAME];
49     uriInfo.storeName = splitUri[STORE_NAME];
50     uriInfo.tableName = splitUri[TABLE_NAME];
51     return true;
52 }
53 
IsDataProxyURI(const std::string & uri)54 bool URIUtils::IsDataProxyURI(const std::string &uri)
55 {
56     return uri.compare(0, DATA_PROXY_SCHEMA_LEN, URIUtils::DATA_PROXY_SCHEMA) == 0;
57 }
58 
GetBundleNameFromProxyURI(const std::string & uri,std::string & bundleName)59 bool URIUtils::GetBundleNameFromProxyURI(const std::string &uri, std::string &bundleName)
60 {
61     Uri uriTemp(uri);
62     if (!uriTemp.GetAuthority().empty()) {
63         bundleName = uriTemp.GetAuthority();
64     }
65     return true;
66 }
67 
GetAppIndexFromProxyURI(const std::string & uri,int32_t & appIndex)68 bool URIUtils::GetAppIndexFromProxyURI(const std::string &uri, int32_t &appIndex)
69 {
70     auto queryParams = URIUtils::GetQueryParams(uri);
71     if (!queryParams[APP_INDEX].empty()) {
72         auto [success, data] = URIUtils::Strtoul(queryParams[APP_INDEX]);
73         if (!success) {
74             appIndex = -1;
75             ZLOGE("appIndex is invalid! appIndex: %{public}s", queryParams[APP_INDEX].c_str());
76             return false;
77         }
78         appIndex = static_cast<int32_t>(data);
79     }
80     return true;
81 }
82 
GetUserFromProxyURI(const std::string & uri)83 std::pair<bool, int32_t> URIUtils::GetUserFromProxyURI(const std::string &uri)
84 {
85     auto queryParams = URIUtils::GetQueryParams(uri);
86     if (queryParams[USER_PARAM].empty()) {
87         // -1 is placeholder for visit provider's user
88         return std::make_pair(true, -1);
89     }
90     auto [success, data] = URIUtils::Strtoul(queryParams[USER_PARAM]);
91     if (!success) {
92         return std::make_pair(false, -1);
93     }
94     if (data < 0 || data > INT32_MAX) {
95         return std::make_pair(false, -1);
96     }
97     return std::make_pair(true, data);
98 }
99 
FormatUri(std::string & uri)100 void URIUtils::FormatUri(std::string &uri)
101 {
102     auto pos = uri.find_last_of('?');
103     if (pos == std::string::npos) {
104         return;
105     }
106 
107     uri.resize(pos);
108 }
109 
FormatConstUri(const std::string & uri)110 std::string URIUtils::FormatConstUri(const std::string &uri)
111 {
112     auto pos = uri.find_last_of('?');
113     if (pos == std::string::npos) {
114         return uri;
115     }
116 
117     return uri.substr(0, pos);
118 }
119 
GetUriConfig(const std::string & uri)120 __attribute__((no_sanitize("cfi"))) UriConfig URIUtils::GetUriConfig(const std::string &uri)
121 {
122     UriConfig uriConfig;
123     Uri uriTemp(uri);
124     uriConfig.authority = uriTemp.GetAuthority();
125     uriConfig.path = uriTemp.GetPath();
126     uriTemp.GetPathSegments(uriConfig.pathSegments);
127     uriConfig.scheme = uriTemp.GetScheme();
128     std::string convertUri = DATA_PROXY_SCHEMA + uriConfig.authority + uriConfig.path;
129     size_t schemePos = convertUri.find(PARAM_URI_SEPARATOR);
130     if (schemePos != std::string::npos) {
131         convertUri.replace(schemePos, PARAM_URI_SEPARATOR_LEN, SCHEME_SEPARATOR);
132     }
133     uriConfig.formatUri = convertUri;
134     return uriConfig;
135 }
136 
Anonymous(const std::string & uri)137 std::string URIUtils::Anonymous(const std::string &uri)
138 {
139     if (uri.length() <= END_LENGTH) {
140         return DEFAULT_ANONYMOUS;
141     }
142 
143     return (DEFAULT_ANONYMOUS + uri.substr(uri.length() - END_LENGTH, END_LENGTH));
144 }
145 
Strtoul(const std::string & str)146 std::pair<bool, uint32_t> URIUtils::Strtoul(const std::string &str)
147 {
148     unsigned long data = 0;
149     if (str.empty()) {
150         return std::make_pair(false, data);
151     }
152     char* end = nullptr;
153     errno = 0;
154     data = strtoul(str.c_str(), &end, END_LENGTH);
155     if (errno == ERANGE || end == nullptr || end == str || *end != '\0') {
156         return std::make_pair(false, data);
157     }
158     return std::make_pair(true, data);
159 }
160 
GetQueryParams(const std::string & uri)161 std::map<std::string, std::string> URIUtils::GetQueryParams(const std::string& uri)
162 {
163     size_t queryStartPos = uri.find('?');
164     if (queryStartPos == std::string::npos) {
165         return {};
166     }
167     std::map<std::string, std::string> params;
168     std::string queryParams = uri.substr(queryStartPos + 1);
169     size_t startPos = 0;
170     while (startPos < queryParams.size()) {
171         size_t delimiterIndex = queryParams.find('&', startPos);
172         if (delimiterIndex == std::string::npos) {
173             delimiterIndex = queryParams.size();
174         }
175         size_t equalIndex = queryParams.find('=', startPos);
176         if (equalIndex == std::string::npos || equalIndex > delimiterIndex) {
177             startPos = delimiterIndex + 1;
178             continue;
179         }
180         std::string key = queryParams.substr(startPos, equalIndex - startPos);
181         std::string value = queryParams.substr(equalIndex + 1, delimiterIndex - equalIndex - 1);
182         params[key] = value;
183         startPos = delimiterIndex + 1;
184     }
185     return params;
186 }
187 
GeneralAnonymous(const std::string & name)188 std::string StringUtils::GeneralAnonymous(const std::string &name)
189 {
190     // To short to be partial anonymized
191     if (name.length() <= REVEAL_SIZE) {
192         return DEFAULT_ANONYMOUS;
193     }
194 
195     // only leave HEAD
196     if (name.length() <= (REVEAL_SIZE + REVEAL_SIZE)) {
197         return (name.substr(0, REVEAL_SIZE) + REPLACE_CHAIN);
198     }
199     // leave 4 char at head and tail respectively
200     return (name.substr(0, REVEAL_SIZE) + REPLACE_CHAIN + name.substr(name.length() - REVEAL_SIZE, REVEAL_SIZE));
201 }
202 
203 } // namespace OHOS::DataShare