1 /*
2 * Copyright (c) 2022 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 "dm_anonymous.h"
17 #include "dm_log.h"
18 #include <sstream>
19 namespace OHOS {
20 namespace DistributedHardware {
21 namespace {
22 constexpr uint32_t MAX_MESSAGE_LEN = 40 * 1024 * 1024;
23 constexpr uint32_t MAX_MAP_LEN = 1000;
24 constexpr uint32_t MAX_INT_LEN = 20;
25 constexpr uint32_t MAX_ID_LEN = 256;
26 }
27 const char* PRINT_LIST_SPLIT = ", ";
28 const int32_t LIST_SPLIT_LEN = 2;
29
GetAnonyString(const std::string & value)30 std::string GetAnonyString(const std::string &value)
31 {
32 const size_t shortIdLengthInt32 = 20;
33 const size_t plaintextLengthInt32 = 4;
34 const size_t minIdLengthInt32 = 3;
35
36 std::string tmpStr("******");
37 size_t strLen = value.length();
38 if (strLen < minIdLengthInt32) {
39 return tmpStr;
40 }
41
42 std::string res;
43 if (strLen <= shortIdLengthInt32) {
44 res += value[0];
45 res += tmpStr;
46 res += value[strLen - 1];
47 } else {
48 res.append(value, 0, plaintextLengthInt32);
49 res += tmpStr;
50 res.append(value, strLen - plaintextLengthInt32, plaintextLengthInt32);
51 }
52
53 return res;
54 }
55
GetAnonyStringList(const std::vector<std::string> & values)56 std::string GetAnonyStringList(const std::vector<std::string> &values)
57 {
58 std::string temp = "[ ";
59 bool flag = false;
60 for (auto const &v : values) {
61 temp += GetAnonyString(v) + PRINT_LIST_SPLIT;
62 flag = true;
63 }
64 if (flag) {
65 temp.erase(temp.length() - LIST_SPLIT_LEN);
66 }
67 temp += " ]";
68 return temp;
69 }
70
GetAnonyInt32(const int32_t value)71 std::string GetAnonyInt32(const int32_t value)
72 {
73 std::string tempString = std::to_string(value);
74 size_t length = tempString.length();
75 if (length == 0x01) {
76 tempString[0] = '*';
77 return tempString;
78 }
79 for (size_t i = 1; i < length - 1; i++) {
80 tempString[i] = '*';
81 }
82 return tempString;
83 }
84
GetAnonyInt32List(const std::vector<int32_t> & values)85 std::string GetAnonyInt32List(const std::vector<int32_t> &values)
86 {
87 std::string temp = "[ ";
88 bool flag = false;
89 for (auto const &v : values) {
90 temp += GetAnonyInt32(v) + PRINT_LIST_SPLIT;
91 flag = true;
92 }
93 if (flag) {
94 temp.erase(temp.length() - LIST_SPLIT_LEN);
95 }
96 temp += " ]";
97 return temp;
98 }
99
IsNumberString(const std::string & inputString)100 bool IsNumberString(const std::string &inputString)
101 {
102 if (inputString.length() == 0 || inputString.length() > MAX_INT_LEN) {
103 LOGE("inputString is Null or inputString length is too long");
104 return false;
105 }
106 const int32_t minAsciiNum = 48;
107 const int32_t maxAsciiNum = 57;
108 for (size_t i = 0; i < inputString.length(); i++) {
109 int num = (int)inputString[i];
110 if (num >= minAsciiNum && num <= maxAsciiNum) {
111 continue;
112 } else {
113 return false;
114 }
115 }
116 return true;
117 }
118
IsString(const JsonItemObject & jsonObj,const std::string & key)119 bool IsString(const JsonItemObject &jsonObj, const std::string &key)
120 {
121 bool res = (jsonObj.Contains(key) && jsonObj[key].IsString()
122 && jsonObj[key].Get<std::string>().size() <= MAX_MESSAGE_LEN);
123 if (!res) {
124 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
125 }
126 return res;
127 }
128
IsInt32(const JsonItemObject & jsonObj,const std::string & key)129 bool IsInt32(const JsonItemObject &jsonObj, const std::string &key)
130 {
131 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<int64_t>() >= INT32_MIN &&
132 jsonObj[key].Get<int64_t>() <= INT32_MAX;
133 if (!res) {
134 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
135 }
136 return res;
137 }
138
IsUint32(const JsonItemObject & jsonObj,const std::string & key)139 bool IsUint32(const JsonItemObject &jsonObj, const std::string &key)
140 {
141 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<int64_t>() >= 0 &&
142 jsonObj[key].Get<int64_t>() <= UINT32_MAX;
143 if (!res) {
144 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
145 }
146 return res;
147 }
148
IsInt64(const JsonItemObject & jsonObj,const std::string & key)149 bool IsInt64(const JsonItemObject &jsonObj, const std::string &key)
150 {
151 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<int64_t>() >= INT64_MIN &&
152 jsonObj[key].Get<int64_t>() <= INT64_MAX;
153 if (!res) {
154 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
155 }
156 return res;
157 }
158
IsArray(const JsonItemObject & jsonObj,const std::string & key)159 bool IsArray(const JsonItemObject &jsonObj, const std::string &key)
160 {
161 bool res = jsonObj.Contains(key) && jsonObj[key].IsArray();
162 if (!res) {
163 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
164 }
165 return res;
166 }
167
IsBool(const JsonItemObject & jsonObj,const std::string & key)168 bool IsBool(const JsonItemObject &jsonObj, const std::string &key)
169 {
170 bool res = jsonObj.Contains(key) && jsonObj[key].IsBoolean();
171 if (!res) {
172 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
173 }
174 return res;
175 }
176
ConvertMapToJsonString(const std::map<std::string,std::string> & paramMap)177 std::string ConvertMapToJsonString(const std::map<std::string, std::string> ¶mMap)
178 {
179 std::string jsonStr = "";
180 if (paramMap.size() > MAX_MAP_LEN) {
181 LOGE("invalid paramMap");
182 return jsonStr;
183 }
184 if (!paramMap.empty()) {
185 JsonObject jsonObj;
186 for (const auto &it : paramMap) {
187 jsonObj[it.first] = it.second;
188 }
189 jsonStr = SafetyDump(jsonObj);
190 }
191 return jsonStr;
192 }
193
ParseMapFromJsonString(const std::string & jsonStr,std::map<std::string,std::string> & paramMap)194 void ParseMapFromJsonString(const std::string &jsonStr, std::map<std::string, std::string> ¶mMap)
195 {
196 if (jsonStr.empty()) {
197 return;
198 }
199 if (paramMap.size() > MAX_MAP_LEN) {
200 LOGE("invalid paramMap");
201 return;
202 }
203 JsonObject paramJson(jsonStr);
204 if (paramJson.IsDiscarded()) {
205 return;
206 }
207 for (auto &element : paramJson.Items()) {
208 if (element.IsString()) {
209 paramMap.insert(std::pair<std::string, std::string>(element.Key(), element.Get<std::string>()));
210 }
211 }
212 }
213
IsInvalidPeerTargetId(const PeerTargetId & targetId)214 bool IsInvalidPeerTargetId(const PeerTargetId &targetId)
215 {
216 return targetId.deviceId.empty() && targetId.brMac.empty() && targetId.bleMac.empty() && targetId.wifiIp.empty();
217 }
218
ConvertCharArray2String(const char * srcData,uint32_t srcLen)219 std::string ConvertCharArray2String(const char *srcData, uint32_t srcLen)
220 {
221 if (srcData == nullptr || srcLen == 0 || srcLen >= MAX_MESSAGE_LEN) {
222 LOGE("Invalid parameter.");
223 return "";
224 }
225 char *dstData = new char[srcLen + 1]();
226 if (memcpy_s(dstData, srcLen + 1, srcData, srcLen) != 0) {
227 LOGE("memcpy_s failed.");
228 delete[] dstData;
229 return "";
230 }
231 std::string temp(dstData);
232 delete[] dstData;
233 return temp;
234 }
235
StringToInt(const std::string & str,int32_t base)236 int32_t StringToInt(const std::string &str, int32_t base)
237 {
238 if (str.empty()) {
239 LOGE("Str is empty.");
240 return 0;
241 }
242 char *nextPtr = nullptr;
243 long result = strtol(str.c_str(), &nextPtr, base);
244 if (errno == ERANGE || *nextPtr != '\0') {
245 LOGE("parse int error");
246 return 0;
247 }
248 return static_cast<int32_t>(result);
249 }
250
StringToInt64(const std::string & str,int32_t base)251 int64_t StringToInt64(const std::string &str, int32_t base)
252 {
253 if (str.empty()) {
254 LOGE("Str is empty.");
255 return 0;
256 }
257 char *nextPtr = nullptr;
258 int64_t result = strtoll(str.c_str(), &nextPtr, base);
259 if (errno == ERANGE || nextPtr == nullptr || nextPtr == str.c_str() || *nextPtr != '\0') {
260 LOGE("parse int error");
261 return 0;
262 }
263 return result;
264 }
265
VersionSplitToInt(const std::string & str,const char split,std::vector<int> & numVec)266 void VersionSplitToInt(const std::string &str, const char split, std::vector<int> &numVec)
267 {
268 std::istringstream iss(str);
269 std::string item = "";
270 while (getline(iss, item, split)) {
271 numVec.push_back(atoi(item.c_str()));
272 }
273 }
274
CompareVecNum(const std::vector<int32_t> & srcVecNum,const std::vector<int32_t> & sinkVecNum)275 bool CompareVecNum(const std::vector<int32_t> &srcVecNum, const std::vector<int32_t> &sinkVecNum)
276 {
277 for (uint32_t index = 0; index < std::min(srcVecNum.size(), sinkVecNum.size()); index++) {
278 if (srcVecNum[index] > sinkVecNum[index]) {
279 return true;
280 } else if (srcVecNum[index] < sinkVecNum[index]) {
281 return false;
282 } else {
283 continue;
284 }
285 }
286 if (srcVecNum.size() > sinkVecNum.size()) {
287 return true;
288 }
289 return false;
290 }
291
CompareVersion(const std::string & remoteVersion,const std::string & oldVersion)292 bool CompareVersion(const std::string &remoteVersion, const std::string &oldVersion)
293 {
294 LOGI("remoteVersion %{public}s, oldVersion %{public}s.", remoteVersion.c_str(), oldVersion.c_str());
295 std::vector<int32_t> remoteVersionVec;
296 std::vector<int32_t> oldVersionVec;
297 VersionSplitToInt(remoteVersion, '.', remoteVersionVec);
298 VersionSplitToInt(oldVersion, '.', oldVersionVec);
299 return CompareVecNum(remoteVersionVec, oldVersionVec);
300 }
301
ComposeStr(const std::string & pkgName,uint16_t subscribeId)302 std::string ComposeStr(const std::string &pkgName, uint16_t subscribeId)
303 {
304 std::string strTemp = pkgName + "#" + std::to_string(subscribeId);
305 return strTemp;
306 }
307
GetCallerPkgName(const std::string & pkgName)308 std::string GetCallerPkgName(const std::string &pkgName)
309 {
310 std::istringstream stream(pkgName);
311 std::string item = "";
312 getline(stream, item, '#');
313 return item;
314 }
315
GetSubscribeId(const std::string & pkgName)316 uint16_t GetSubscribeId(const std::string &pkgName)
317 {
318 std::vector<std::string> strVec;
319 size_t subIdIndex = 1;
320 size_t start = 0;
321 size_t end = pkgName.find("#");
322
323 while (end != std::string::npos) {
324 strVec.push_back(pkgName.substr(start, end - start));
325 start = end + 1;
326 end = pkgName.find("#", start);
327 }
328 strVec.push_back(pkgName.substr(start));
329 if (strVec.size() >= subIdIndex + 1) {
330 return std::atoi(strVec.at(subIdIndex).c_str());
331 }
332 return 0;
333 }
334
IsIdLengthValid(const std::string & inputID)335 bool IsIdLengthValid(const std::string &inputID)
336 {
337 if (inputID.empty() || inputID.length() > MAX_ID_LEN) {
338 LOGE("On parameter length error, maybe empty or beyond MAX_ID_LEN!");
339 return false;
340 }
341 return true;
342 }
343
IsMessageLengthValid(const std::string & inputMessage)344 bool IsMessageLengthValid(const std::string &inputMessage)
345 {
346 if (inputMessage.empty() || inputMessage.length() > MAX_MESSAGE_LEN) {
347 LOGE("On parameter error, maybe empty or beyond MAX_MESSAGE_LEN!");
348 return false;
349 }
350 return true;
351 }
352
IsValueExist(const std::multimap<std::string,int32_t> unorderedmap,const std::string & udid,int32_t userId)353 bool IsValueExist(const std::multimap<std::string, int32_t> unorderedmap, const std::string &udid, int32_t userId)
354 {
355 for (const auto &item : unorderedmap) {
356 if (item.first == udid && item.second == userId) {
357 return true;
358 }
359 }
360 return false;
361 }
362
IsDmCommonNotifyEventValid(DmCommonNotifyEvent dmCommonNotifyEvent)363 bool IsDmCommonNotifyEventValid(DmCommonNotifyEvent dmCommonNotifyEvent)
364 {
365 if (dmCommonNotifyEvent > DmCommonNotifyEvent::MIN && dmCommonNotifyEvent < DmCommonNotifyEvent::MAX) {
366 return true;
367 }
368 return false;
369 }
370
SafetyDump(const JsonItemObject & jsonObj)371 std::string SafetyDump(const JsonItemObject &jsonObj)
372 {
373 return jsonObj.Dump();
374 }
375
GetSubStr(const std::string & rawStr,const std::string & separator,int32_t index)376 std::string GetSubStr(const std::string &rawStr, const std::string &separator, int32_t index)
377 {
378 if (rawStr.empty() || separator.empty() || index < 0) {
379 LOGE("param invalid");
380 return "";
381 }
382 std::vector<std::string> strVec;
383 size_t start = 0;
384 size_t end = rawStr.find(separator);
385
386 while (end != std::string::npos) {
387 strVec.push_back(rawStr.substr(start, end - start));
388 start = end + separator.size();
389 end = rawStr.find(separator, start);
390 }
391 strVec.push_back(rawStr.substr(start));
392 if (strVec.size() >= static_cast<size_t>(index + 1)) {
393 return strVec.at(index);
394 }
395 LOGE("get failed");
396 return "";
397 }
398
IsJsonValIntegerString(const JsonItemObject & jsonObj,const std::string & key)399 bool IsJsonValIntegerString(const JsonItemObject &jsonObj, const std::string &key)
400 {
401 if (!IsString(jsonObj, key)) {
402 LOGE("%{public}s is not string", key.c_str());
403 return false;
404 }
405 std::string retValStr = jsonObj[key].Get<std::string>();
406 if (!IsNumberString(retValStr)) {
407 LOGE("%{public}s is not number", key.c_str());
408 return false;
409 }
410 return true;
411 }
412 } // namespace DistributedHardware
413 } // namespace OHOS