• 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 "URIUtils"
16 
17 #include "uri_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 {
GetInfoFromURI(const std::string & uri,UriInfo & uriInfo)27 bool URIUtils::GetInfoFromURI(const std::string &uri, UriInfo &uriInfo)
28 {
29     Uri uriTemp(uri);
30     std::vector<std::string> splitUri;
31     SplitStr(uriTemp.GetPath(), "/", splitUri);
32     if (splitUri.size() < PARAM_SIZE) {
33         ZLOGE("Invalid uri: %{public}s", DistributedData::Anonymous::Change(uri).c_str());
34         return false;
35     }
36 
37     if (splitUri[BUNDLE_NAME].empty() || splitUri[MODULE_NAME].empty() ||
38         splitUri[STORE_NAME].empty() || splitUri[TABLE_NAME].empty()) {
39         ZLOGE("Uri has empty field! bundleName: %{public}s  uri: %{public}s", splitUri[BUNDLE_NAME].c_str(),
40             DistributedData::Anonymous::Change(uri).c_str());
41         return false;
42     }
43 
44     uriInfo.bundleName = splitUri[BUNDLE_NAME];
45     uriInfo.moduleName = splitUri[MODULE_NAME];
46     uriInfo.storeName = splitUri[STORE_NAME];
47     uriInfo.tableName = splitUri[TABLE_NAME];
48     return true;
49 }
50 
IsDataProxyURI(const std::string & uri)51 bool URIUtils::IsDataProxyURI(const std::string &uri)
52 {
53     return uri.compare(0, DATA_PROXY_SCHEMA_LEN, URIUtils::DATA_PROXY_SCHEMA) == 0;
54 }
55 
GetBundleNameFromProxyURI(const std::string & uri,std::string & bundleName)56 bool URIUtils::GetBundleNameFromProxyURI(const std::string &uri, std::string &bundleName)
57 {
58     Uri uriTemp(uri);
59     if (!uriTemp.GetAuthority().empty()) {
60         bundleName = uriTemp.GetAuthority();
61     }
62     return true;
63 }
64 
GetAppIndexFromProxyURI(const std::string & uri,int32_t & appIndex)65 bool URIUtils::GetAppIndexFromProxyURI(const std::string &uri, int32_t &appIndex)
66 {
67     auto queryParams = URIUtils::GetQueryParams(uri);
68     if (!queryParams[APP_INDEX].empty()) {
69         auto [success, data] = URIUtils::Strtoul(queryParams[APP_INDEX]);
70         if (!success) {
71             appIndex = -1;
72             ZLOGE("appIndex is invalid! appIndex: %{public}s", queryParams[APP_INDEX].c_str());
73             return false;
74         }
75         appIndex = static_cast<int32_t>(data);
76     }
77     return true;
78 }
79 
GetUserFromProxyURI(const std::string & uri)80 std::pair<bool, int32_t> URIUtils::GetUserFromProxyURI(const std::string &uri)
81 {
82     auto queryParams = URIUtils::GetQueryParams(uri);
83     if (queryParams[USER_PARAM].empty()) {
84         // -1 is placeholder for visit provider's user
85         return std::make_pair(true, -1);
86     }
87     auto [success, data] = URIUtils::Strtoul(queryParams[USER_PARAM]);
88     if (!success) {
89         return std::make_pair(false, -1);
90     }
91     if (data < 0 || data > INT32_MAX) {
92         return std::make_pair(false, -1);
93     }
94     return std::make_pair(true, data);
95 }
96 
FormatUri(std::string & uri)97 void URIUtils::FormatUri(std::string &uri)
98 {
99     auto pos = uri.find_last_of('?');
100     if (pos == std::string::npos) {
101         return;
102     }
103 
104     uri.resize(pos);
105 }
106 
FormatConstUri(const std::string & uri)107 std::string URIUtils::FormatConstUri(const std::string &uri)
108 {
109     auto pos = uri.find_last_of('?');
110     if (pos == std::string::npos) {
111         return uri;
112     }
113 
114     return uri.substr(0, pos);
115 }
116 
GetUriConfig(const std::string & uri)117 __attribute__((no_sanitize("cfi"))) UriConfig URIUtils::GetUriConfig(const std::string &uri)
118 {
119     UriConfig uriConfig;
120     Uri uriTemp(uri);
121     uriConfig.authority = uriTemp.GetAuthority();
122     uriConfig.path = uriTemp.GetPath();
123     uriTemp.GetPathSegments(uriConfig.pathSegments);
124     uriConfig.scheme = uriTemp.GetScheme();
125     std::string convertUri = DATA_PROXY_SCHEMA + uriConfig.authority + uriConfig.path;
126     size_t schemePos = convertUri.find(PARAM_URI_SEPARATOR);
127     if (schemePos != std::string::npos) {
128         convertUri.replace(schemePos, PARAM_URI_SEPARATOR_LEN, SCHEME_SEPARATOR);
129     }
130     uriConfig.formatUri = convertUri;
131     return uriConfig;
132 }
133 
Anonymous(const std::string & uri)134 std::string URIUtils::Anonymous(const std::string &uri)
135 {
136     if (uri.length() <= END_LENGTH) {
137         return DEFAULT_ANONYMOUS;
138     }
139 
140     return (DEFAULT_ANONYMOUS + uri.substr(uri.length() - END_LENGTH, END_LENGTH));
141 }
142 
Strtoul(const std::string & str)143 std::pair<bool, uint32_t> URIUtils::Strtoul(const std::string &str)
144 {
145     unsigned long data = 0;
146     if (str.empty()) {
147         return std::make_pair(false, data);
148     }
149     char* end = nullptr;
150     errno = 0;
151     data = strtoul(str.c_str(), &end, 10);
152     if (errno == ERANGE || end == nullptr || end == str || *end != '\0') {
153         return std::make_pair(false, data);
154     }
155     return std::make_pair(true, data);
156 }
157 
GetQueryParams(const std::string & uri)158 std::map<std::string, std::string> URIUtils::GetQueryParams(const std::string& uri)
159 {
160     size_t queryStartPos = uri.find('?');
161     if (queryStartPos == std::string::npos) {
162         return {};
163     }
164     std::map<std::string, std::string> params;
165     std::string queryParams = uri.substr(queryStartPos + 1);
166     size_t startPos = 0;
167     while (startPos < queryParams.size()) {
168         size_t delimiterIndex = queryParams.find('&', startPos);
169         if (delimiterIndex == std::string::npos) {
170             delimiterIndex = queryParams.size();
171         }
172         size_t equalIndex = queryParams.find('=', startPos);
173         if (equalIndex == std::string::npos || equalIndex > delimiterIndex) {
174             startPos = delimiterIndex + 1;
175             continue;
176         }
177         std::string key = queryParams.substr(startPos, equalIndex - startPos);
178         std::string value = queryParams.substr(equalIndex + 1, delimiterIndex - equalIndex - 1);
179         params[key] = value;
180         startPos = delimiterIndex + 1;
181     }
182     return params;
183 }
184 } // namespace OHOS::DataShare