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 "app_log_wrapper.h"
17 #include "skill.h"
18 #include <regex>
19 #include <unistd.h>
20 #include "mime_type_mgr.h"
21 #include "parcel_macro.h"
22 #include "json_util.h"
23 #include <fcntl.h>
24 #include "nlohmann/json.hpp"
25 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
26 #include "type_descriptor.h"
27 #include "utd_client.h"
28 #endif
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 constexpr const char* JSON_KEY_TYPE = "type";
34 constexpr const char* JSON_KEY_PERMISSIONS = "permissions";
35 constexpr const char* JSON_KEY_ACTIONS = "actions";
36 constexpr const char* JSON_KEY_ENTITIES = "entities";
37 constexpr const char* JSON_KEY_URIS = "uris";
38 constexpr const char* JSON_KEY_SCHEME = "scheme";
39 constexpr const char* JSON_KEY_HOST = "host";
40 constexpr const char* JSON_KEY_PORT = "port";
41 constexpr const char* JSON_KEY_PATH = "path";
42 constexpr const char* JSON_KEY_PATHSTARTWITH = "pathStartWith";
43 constexpr const char* JSON_KEY_PATHREGEX = "pathRegex";
44 constexpr const char* JSON_KEY_UTD = "utd";
45 constexpr const char* JSON_KEY_MAXFILESUPPORTED = "maxFileSupported";
46 constexpr const char* JSON_KEY_LINKFEATURE = "linkFeature";
47 constexpr const char* JSON_KEY_DOMAINVERIFY = "domainVerify";
48 constexpr const char* BUNDLE_MODULE_PROFILE_KEY_PATHREGX = "pathRegx";
49 constexpr const char* PARAM_SEPARATOR = "?";
50 constexpr const char* PORT_SEPARATOR = ":";
51 constexpr const char* SCHEME_SEPARATOR = "://";
52 constexpr const char* PATH_SEPARATOR = "/";
53 constexpr const char* TYPE_WILDCARD = "*/*";
54 const char WILDCARD = '*';
55 constexpr const char* TYPE_ONLY_MATCH_WILDCARD = "reserved/wildcard";
56 const char* LINK_FEATURE = "linkFeature";
57 const char* GENERAL_OBJECT = "general.object";
58 const uint32_t PROTOCOL_OFFSET = 3;
59 }; // namespace
60
Match(const OHOS::AAFwk::Want & want) const61 bool Skill::Match(const OHOS::AAFwk::Want &want) const
62 {
63 std::string linkFeature = want.GetStringParam(LINK_FEATURE);
64 if (!linkFeature.empty()) {
65 size_t matchUriIndex = 0;
66 return MatchLinkFeature(linkFeature, want, matchUriIndex);
67 }
68
69 if (!MatchLauncher(want)) {
70 APP_LOGD("Action or entities does not match");
71 return false;
72 }
73 std::vector<std::string> vecTypes = want.GetStringArrayParam(OHOS::AAFwk::Want::PARAM_ABILITY_URITYPES);
74 std::string uriString = want.GetUriString();
75 if (!vecTypes.empty()) {
76 for (std::string strType : vecTypes) {
77 if (MatchUriAndType(uriString, strType)) {
78 APP_LOGD("type %{public}s, Is Matched", strType.c_str());
79 return true;
80 }
81 }
82 return false;
83 }
84 bool matchUriAndType = MatchUriAndType(uriString, want.GetType());
85 if (!matchUriAndType) {
86 APP_LOGD("Uri or Type does not match");
87 return false;
88 }
89 return true;
90 }
91
Match(const OHOS::AAFwk::Want & want,size_t & matchUriIndex) const92 bool Skill::Match(const OHOS::AAFwk::Want &want, size_t &matchUriIndex) const
93 {
94 std::string linkFeature = want.GetStringParam(LINK_FEATURE);
95 if (!linkFeature.empty()) {
96 return MatchLinkFeature(linkFeature, want, matchUriIndex);
97 }
98
99 if (!MatchLauncher(want)) {
100 APP_LOGD("Action or entities does not match");
101 return false;
102 }
103
104 std::vector<std::string> vecTypes = want.GetStringArrayParam(OHOS::AAFwk::Want::PARAM_ABILITY_URITYPES);
105 if (vecTypes.size() > 0) {
106 for (std::string strType : vecTypes) {
107 if (MatchUriAndType(want.GetUriString(), strType, matchUriIndex)) {
108 APP_LOGD("type %{public}s, Is Matched", strType.c_str());
109 return true;
110 }
111 }
112 return false;
113 }
114 bool matchUriAndType = MatchUriAndType(want.GetUriString(), want.GetType(), matchUriIndex);
115 if (!matchUriAndType) {
116 APP_LOGD("Uri or Type does not match");
117 return false;
118 }
119 return true;
120 }
121
122
MatchLauncher(const OHOS::AAFwk::Want & want) const123 bool Skill::MatchLauncher(const OHOS::AAFwk::Want &want) const
124 {
125 bool matchAction = MatchAction(want.GetAction());
126 if (!matchAction) {
127 APP_LOGD("Action does not match");
128 return false;
129 }
130 bool matchEntities = MatchEntities(want.GetEntities());
131 if (!matchEntities) {
132 APP_LOGD("Entities does not match");
133 return false;
134 }
135 return true;
136 }
137
MatchAction(const std::string & action) const138 bool Skill::MatchAction(const std::string &action) const
139 {
140 // config actions empty, no match
141 if (actions.empty()) {
142 return false;
143 }
144 // config actions not empty, param empty, match
145 if (action.empty()) {
146 return true;
147 }
148 auto actionMatcher = [action] (const std::string &configAction) {
149 if (action == configAction) {
150 return true;
151 }
152 if (action == Constants::ACTION_HOME && configAction == Constants::WANT_ACTION_HOME) {
153 return true;
154 }
155 if (action == Constants::WANT_ACTION_HOME && configAction == Constants::ACTION_HOME) {
156 return true;
157 }
158 return false;
159 };
160 // config actions not empty, param not empty, if config actions contains param action, match
161 return std::find_if(actions.cbegin(), actions.cend(), actionMatcher) != actions.cend();
162 }
163
MatchEntities(const std::vector<std::string> & paramEntities) const164 bool Skill::MatchEntities(const std::vector<std::string> ¶mEntities) const
165 {
166 // param entities empty, match
167 if (paramEntities.empty()) {
168 return true;
169 }
170 // config entities empty, param entities not empty, not match
171 if (entities.empty()) {
172 return false;
173 }
174 // config entities not empty, param entities not empty, if every param entity in config entities, match
175 std::vector<std::string>::size_type size = paramEntities.size();
176 for (std::vector<std::string>::size_type i = 0; i < size; i++) {
177 bool ret = std::find(entities.cbegin(), entities.cend(), paramEntities[i]) == entities.cend();
178 if (ret) {
179 return false;
180 }
181 }
182 return true;
183 }
184
MatchUriAndType(const std::string & rawUriString,const std::string & type) const185 bool Skill::MatchUriAndType(const std::string &rawUriString, const std::string &type) const
186 {
187 const std::string uriString = GetOptParamUri(rawUriString);
188 if (uriString.empty() && type.empty()) {
189 // case1 : param uri empty, param type empty
190 if (uris.empty()) {
191 return true;
192 }
193 for (const SkillUri &skillUri : uris) {
194 if (skillUri.scheme.empty() && skillUri.type.empty()) {
195 return true;
196 }
197 }
198 return false;
199 }
200 if (uris.empty()) {
201 return false;
202 }
203 if (!uriString.empty() && type.empty()) {
204 // case2 : param uri not empty, param type empty
205 for (const SkillUri &skillUri : uris) {
206 if (MatchUri(uriString, skillUri) && skillUri.type.empty()) {
207 return true;
208 }
209 }
210 // if uri is a file path, match type by the suffix
211 return MatchMimeType(uriString);
212 } else if (uriString.empty() && !type.empty()) {
213 // case3 : param uri empty, param type not empty
214 for (const SkillUri &skillUri : uris) {
215 if (skillUri.scheme.empty() && MatchType(type, skillUri.type)) {
216 return true;
217 }
218 }
219 return false;
220 } else {
221 // case4 : param uri not empty, param type not empty
222 for (const SkillUri &skillUri : uris) {
223 if (MatchUri(uriString, skillUri) && MatchType(type, skillUri.type)) {
224 return true;
225 }
226 }
227 return false;
228 }
229 }
230
MatchLinkFeature(const std::string & linkFeature,const OHOS::AAFwk::Want & want,size_t & matchUriIndex) const231 bool Skill::MatchLinkFeature(const std::string &linkFeature, const OHOS::AAFwk::Want &want, size_t &matchUriIndex) const
232 {
233 std::string paramUriString = GetOptParamUri(want.GetUriString());
234 std::string paramType = want.GetType();
235 // only linkFeature
236 if (paramUriString.empty() && paramType.empty()) {
237 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
238 const SkillUri &skillUri = uris[uriIndex];
239 if (linkFeature == skillUri.linkFeature) {
240 matchUriIndex = uriIndex;
241 return true;
242 }
243 }
244 return false;
245 }
246 // linkFeature + uri + type
247 bool onlyUri = !paramUriString.empty() && paramType.empty();
248 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
249 const SkillUri &skillUri = uris[uriIndex];
250 if (linkFeature != skillUri.linkFeature) {
251 continue;
252 }
253 if (MatchUri(paramUriString, skillUri) && MatchType(paramType, skillUri.type)) {
254 matchUriIndex = uriIndex;
255 return true;
256 }
257 if (!onlyUri) {
258 continue;
259 }
260 std::vector<std::string> paramUtdVector;
261 if (!MimeTypeMgr::GetUtdVectorByUri(paramUriString, paramUtdVector)) {
262 continue;
263 }
264 for (const std::string ¶mUtd : paramUtdVector) {
265 if ((MatchUri(paramUriString, skillUri) ||
266 (skillUri.scheme.empty() && paramUriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
267 MatchType(paramUtd, skillUri.type)) {
268 matchUriIndex = uriIndex;
269 return true;
270 }
271 }
272 }
273 return false;
274 }
275
MatchUriAndType(const std::string & rawUriString,const std::string & type,size_t & matchUriIndex) const276 bool Skill::MatchUriAndType(const std::string &rawUriString, const std::string &type, size_t &matchUriIndex) const
277 {
278 const std::string uriString = GetOptParamUri(rawUriString);
279 if (uriString.empty() && type.empty()) {
280 // case1 : param uri empty, param type empty
281 if (uris.empty()) {
282 return true;
283 }
284 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
285 const SkillUri &skillUri = uris[uriIndex];
286 if (skillUri.scheme.empty() && skillUri.type.empty()) {
287 matchUriIndex = uriIndex;
288 return true;
289 }
290 }
291 return false;
292 }
293 if (uris.empty()) {
294 return false;
295 }
296 if (!uriString.empty() && type.empty()) {
297 // case2 : param uri not empty, param type empty
298 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
299 const SkillUri &skillUri = uris[uriIndex];
300 if (MatchUri(uriString, skillUri) && skillUri.type.empty()) {
301 matchUriIndex = uriIndex;
302 return true;
303 }
304 }
305 // if uri is a file path, match type by the suffix
306 return MatchMimeType(uriString, matchUriIndex);
307 } else if (uriString.empty() && !type.empty()) {
308 // case3 : param uri empty, param type not empty
309 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
310 const SkillUri &skillUri = uris[uriIndex];
311 if (skillUri.scheme.empty() && MatchType(type, skillUri.type)) {
312 matchUriIndex = uriIndex;
313 return true;
314 }
315 }
316 return false;
317 } else {
318 // case4 : param uri not empty, param type not empty
319 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
320 const SkillUri &skillUri = uris[uriIndex];
321 if (MatchUri(uriString, skillUri) && MatchType(type, skillUri.type)) {
322 matchUriIndex = uriIndex;
323 return true;
324 }
325 }
326 return false;
327 }
328 }
329
StartsWith(const std::string & sourceString,const std::string & targetPrefix) const330 bool Skill::StartsWith(const std::string &sourceString, const std::string &targetPrefix) const
331 {
332 return sourceString.rfind(targetPrefix, 0) == 0;
333 }
334
GetOptParamUri(const std::string & uriString)335 std::string Skill::GetOptParamUri(const std::string &uriString)
336 {
337 std::size_t pos = uriString.find(PARAM_SEPARATOR);
338 if (pos == std::string::npos) {
339 return uriString;
340 }
341 return uriString.substr(0, pos);
342 }
343
ConvertUriToLower(const std::string & uri) const344 std::string Skill::ConvertUriToLower(const std::string& uri) const
345 {
346 size_t protocolEnd = uri.find(SCHEME_SEPARATOR);
347 if (protocolEnd == std::string::npos || protocolEnd + PROTOCOL_OFFSET == uri.size()) {
348 return ConvertToLower(uri);
349 }
350 std::string protocol = uri.substr(0, protocolEnd);
351 size_t startHost = protocolEnd + PROTOCOL_OFFSET;
352 size_t endHost = uri.find(PATH_SEPARATOR, startHost);
353 std::string host;
354 if (endHost == std::string::npos) {
355 host = uri.substr(startHost);
356 } else {
357 host = uri.substr(startHost, endHost - startHost);
358 }
359
360 std::string path = (endHost == std::string::npos) ? "" : uri.substr(endHost);
361 std::transform(protocol.begin(), protocol.end(), protocol.begin(), [](unsigned char c) { return std::tolower(c); });
362 std::transform(host.begin(), host.end(), host.begin(), [](unsigned char c) { return std::tolower(c); });
363 return protocol + SCHEME_SEPARATOR + host + path;
364 }
365
ConvertToLower(const std::string & str) const366 inline std::string Skill::ConvertToLower(const std::string &str) const
367 {
368 std::string lowerCaseStr = str;
369 std::transform(lowerCaseStr.begin(), lowerCaseStr.end(), lowerCaseStr.begin(), [](unsigned char c) {
370 return std::tolower(c);
371 });
372 return lowerCaseStr;
373 }
374
MatchUri(const std::string & uriString,const SkillUri & skillUri) const375 bool Skill::MatchUri(const std::string &uriString, const SkillUri &skillUri) const
376 {
377 if (uriString.empty() && skillUri.scheme.empty()) {
378 return true;
379 }
380 if (uriString.empty() || skillUri.scheme.empty()) {
381 return false;
382 }
383 if (skillUri.host.empty()) {
384 // config uri is : scheme
385 // belows are param uri matched conditions:
386 // 1.scheme
387 // 2.scheme:
388 // 3.scheme:/
389 // 4.scheme://
390 std::string uriStr = ConvertUriToLower(GetOptParamUri(uriString));
391 std::string skillScheme = ConvertToLower(skillUri.scheme);
392 return uriStr == skillScheme || StartsWith(uriStr, skillScheme + PORT_SEPARATOR);
393 }
394 std::string optParamUri = ConvertUriToLower(GetOptParamUri(uriString));
395 std::string skillUriTmpString;
396 skillUriTmpString.append(skillUri.scheme).append(SCHEME_SEPARATOR).append(skillUri.host);
397 std::string skillUriString = ConvertUriToLower(skillUriTmpString);
398
399 if (!skillUri.port.empty()) {
400 skillUriString.append(PORT_SEPARATOR).append(skillUri.port);
401 }
402 if (skillUri.path.empty() && skillUri.pathStartWith.empty() && skillUri.pathRegex.empty()) {
403 // with port, config uri is : scheme://host:port
404 // belows are param uri matched conditions:
405 // 1.scheme://host:port
406 // 2.scheme://host:port/path
407
408 // without port, config uri is : scheme://host
409 // belows are param uri matched conditions:
410 // 1.scheme://host
411 // 2.scheme://host/path
412 // 3.scheme://host:port scheme://host:port/path
413 bool ret = (optParamUri == skillUriString || StartsWith(optParamUri, skillUriString + PATH_SEPARATOR));
414 if (skillUri.port.empty()) {
415 ret = ret || StartsWith(optParamUri, skillUriString + PORT_SEPARATOR);
416 }
417 return ret;
418 }
419 skillUriString.append(PATH_SEPARATOR);
420 // if one of path, pathStartWith, pathRegex match, then match
421 if (!skillUri.path.empty()) {
422 // path match
423 std::string pathUri(skillUriString);
424 pathUri.append(skillUri.path);
425 if (optParamUri == pathUri) {
426 return true;
427 }
428 }
429 if (!skillUri.pathStartWith.empty()) {
430 // pathStartWith match
431 std::string pathStartWithUri(skillUriString);
432 pathStartWithUri.append(skillUri.pathStartWith);
433 if (StartsWith(optParamUri, pathStartWithUri)) {
434 return true;
435 }
436 }
437 if (!skillUri.pathRegex.empty()) {
438 // pathRegex match
439 std::string pathRegexUri(skillUriString);
440 pathRegexUri.append(skillUri.pathRegex);
441 try {
442 std::regex regex(pathRegexUri);
443 if (regex_match(optParamUri, regex)) {
444 return true;
445 }
446 } catch (const std::regex_error& e) {
447 APP_LOGE("regex error");
448 }
449 }
450 return false;
451 }
452
MatchType(const std::string & type,const std::string & skillUriType) const453 bool Skill::MatchType(const std::string &type, const std::string &skillUriType) const
454 {
455 if (type.empty() && skillUriType.empty()) {
456 return true;
457 }
458 if (type.empty() || skillUriType.empty()) {
459 return false;
460 }
461
462 // only match */* or general.object
463 if (type == TYPE_ONLY_MATCH_WILDCARD) {
464 return skillUriType == TYPE_WILDCARD || skillUriType == GENERAL_OBJECT;
465 }
466
467 bool containsUtd = false;
468 bool matchUtdRet = MatchUtd(type, skillUriType, containsUtd);
469 if (containsUtd) {
470 return matchUtdRet;
471 }
472
473 if (type == TYPE_WILDCARD || skillUriType == TYPE_WILDCARD) {
474 // param is */* or config is */*
475 return true;
476 }
477 bool paramTypeRegex = type.back() == WILDCARD;
478 if (paramTypeRegex) {
479 // param is string/*
480 std::string prefix = type.substr(0, type.length() - 1);
481 return skillUriType.find(prefix) == 0;
482 }
483 bool typeRegex = skillUriType.back() == WILDCARD;
484 if (typeRegex) {
485 // config is string/*
486 std::string prefix = skillUriType.substr(0, skillUriType.length() - 1);
487 return type.find(prefix) == 0;
488 } else {
489 return type == skillUriType;
490 }
491 }
492
MatchUtd(const std::string & paramType,const std::string & skillUriType,bool & containsUtd) const493 bool Skill::MatchUtd(const std::string ¶mType, const std::string &skillUriType, bool &containsUtd) const
494 {
495 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
496 bool isParamUtd = IsUtd(paramType);
497 bool isSkillUtd = IsUtd(skillUriType);
498
499 containsUtd = isParamUtd || isSkillUtd;
500
501 if (!isParamUtd && !isSkillUtd) {
502 // 1.param : mimeType, skill : mimeType
503 return false;
504 } else if (isParamUtd && isSkillUtd) {
505 // 2.param : utd, skill : utd
506 return IsUtdMatch(paramType, skillUriType);
507 } else if (!isParamUtd && isSkillUtd) {
508 // 3.param : mimeType, skill : utd
509 std::vector<std::string> paramUtdVector;
510 auto ret = UDMF::UtdClient::GetInstance().GetUniformDataTypesByMIMEType(paramType, paramUtdVector);
511 if (ret != ERR_OK || paramUtdVector.empty()) {
512 return false;
513 }
514 for (const std::string ¶mUtd : paramUtdVector) {
515 if (IsUtdMatch(paramUtd, skillUriType)) {
516 return true;
517 }
518 }
519 return false;
520 } else {
521 // 4.param : utd, skill : mimeType
522 std::vector<std::string> skillUtdVector;
523 auto ret = UDMF::UtdClient::GetInstance().GetUniformDataTypesByMIMEType(skillUriType, skillUtdVector);
524 if (ret != ERR_OK || skillUtdVector.empty()) {
525 return false;
526 }
527 for (const std::string &skillUtd : skillUtdVector) {
528 if (IsUtdMatch(paramType, skillUtd)) {
529 return true;
530 }
531 }
532 return false;
533 }
534 #else
535 containsUtd = false;
536 return false;
537 #endif
538 }
539
IsUtdMatch(const std::string & paramUtd,const std::string & skillUtd) const540 bool Skill::IsUtdMatch(const std::string ¶mUtd, const std::string &skillUtd) const
541 {
542 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
543 std::shared_ptr<UDMF::TypeDescriptor> paramTypeDescriptor;
544 auto ret = UDMF::UtdClient::GetInstance().GetTypeDescriptor(paramUtd, paramTypeDescriptor);
545 if (ret != ERR_OK || paramTypeDescriptor == nullptr) {
546 return false;
547 }
548 bool isMatch = false;
549 ret = paramTypeDescriptor->BelongsTo(skillUtd, isMatch);
550 if (ret != ERR_OK) {
551 return false;
552 }
553 return isMatch;
554 #else
555 return false;
556 #endif
557 }
558
IsUtd(const std::string & param) const559 bool Skill::IsUtd(const std::string ¶m) const
560 {
561 #ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED
562 bool isUtd = false;
563 auto ret = UDMF::UtdClient::GetInstance().IsUtd(param, isUtd);
564 return ret == ERR_OK && isUtd;
565 #else
566 return false;
567 #endif
568 }
569
MatchMimeType(const std::string & uriString) const570 bool Skill::MatchMimeType(const std::string & uriString) const
571 {
572 std::vector<std::string> paramUtdVector;
573 if (!MimeTypeMgr::GetUtdVectorByUri(uriString, paramUtdVector)) {
574 return false;
575 }
576 for (const SkillUri &skillUri : uris) {
577 for (const std::string ¶mUtd : paramUtdVector) {
578 if ((MatchUri(uriString, skillUri) ||
579 (skillUri.scheme.empty() && uriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
580 MatchType(paramUtd, skillUri.type)) {
581 return true;
582 }
583 }
584 }
585 return false;
586 }
587
588
MatchMimeType(const std::string & uriString,size_t & matchUriIndex) const589 bool Skill::MatchMimeType(const std::string & uriString, size_t &matchUriIndex) const
590 {
591 std::vector<std::string> paramUtdVector;
592 if (!MimeTypeMgr::GetUtdVectorByUri(uriString, paramUtdVector)) {
593 return false;
594 }
595 for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
596 const SkillUri &skillUri = uris[uriIndex];
597 for (const std::string ¶mUtd : paramUtdVector) {
598 if ((MatchUri(uriString, skillUri) ||
599 (skillUri.scheme.empty() && uriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
600 MatchType(paramUtd, skillUri.type)) {
601 matchUriIndex = uriIndex;
602 return true;
603 }
604 }
605 }
606 return false;
607 }
608
ReadFromParcel(Parcel & parcel)609 bool Skill::ReadFromParcel(Parcel &parcel)
610 {
611 int32_t actionsSize;
612 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, actionsSize);
613 CONTAINER_SECURITY_VERIFY(parcel, actionsSize, &actions);
614 for (auto i = 0; i < actionsSize; i++) {
615 actions.emplace_back(Str16ToStr8(parcel.ReadString16()));
616 }
617
618 int32_t entitiesSize;
619 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, entitiesSize);
620 CONTAINER_SECURITY_VERIFY(parcel, entitiesSize, &entities);
621 for (auto i = 0; i < entitiesSize; i++) {
622 entities.emplace_back(Str16ToStr8(parcel.ReadString16()));
623 }
624
625 int32_t urisSize;
626 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, urisSize);
627 CONTAINER_SECURITY_VERIFY(parcel, urisSize, &uris);
628 for (auto i = 0; i < urisSize; i++) {
629 SkillUri uri;
630 uri.scheme = Str16ToStr8(parcel.ReadString16());
631 uri.host = Str16ToStr8(parcel.ReadString16());
632 uri.port = Str16ToStr8(parcel.ReadString16());
633 uri.path = Str16ToStr8(parcel.ReadString16());
634 uri.pathStartWith = Str16ToStr8(parcel.ReadString16());
635 uri.pathRegex = Str16ToStr8(parcel.ReadString16());
636 uri.type = Str16ToStr8(parcel.ReadString16());
637 uri.utd = Str16ToStr8(parcel.ReadString16());
638 uri.maxFileSupported = parcel.ReadInt32();
639 uri.linkFeature = Str16ToStr8(parcel.ReadString16());
640 uris.emplace_back(uri);
641 }
642
643 int32_t permissionsSize;
644 READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissionsSize);
645 CONTAINER_SECURITY_VERIFY(parcel, permissionsSize, &permissions);
646 for (auto i = 0; i < permissionsSize; i++) {
647 permissions.emplace_back(Str16ToStr8(parcel.ReadString16()));
648 }
649 domainVerify = parcel.ReadBool();
650 return true;
651 }
652
Unmarshalling(Parcel & parcel)653 Skill *Skill::Unmarshalling(Parcel &parcel)
654 {
655 Skill *skill = new (std::nothrow) Skill();
656 if (skill && !skill->ReadFromParcel(parcel)) {
657 APP_LOGW("read from parcel failed");
658 delete skill;
659 skill = nullptr;
660 }
661 return skill;
662 }
663
Marshalling(Parcel & parcel) const664 bool Skill::Marshalling(Parcel &parcel) const
665 {
666 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, actions.size());
667 for (auto &action : actions) {
668 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(action));
669 }
670
671 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, entities.size());
672 for (auto &entitiy : entities) {
673 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(entitiy));
674 }
675
676 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uris.size());
677 for (auto &uri : uris) {
678 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.scheme));
679 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.host));
680 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.port));
681 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.path));
682 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.pathStartWith));
683 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.pathRegex));
684 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.type));
685 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.utd));
686 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, uri.maxFileSupported);
687 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(uri.linkFeature));
688 }
689 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissions.size());
690 for (auto &permission : permissions) {
691 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(permission));
692 }
693 WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, domainVerify);
694 return true;
695 }
696
Dump(std::string prefix,int fd)697 void Skill::Dump(std::string prefix, int fd)
698 {
699 APP_LOGI("called dump Skill");
700 if (fd < 0) {
701 APP_LOGE("dump Skill fd error");
702 return;
703 }
704 int flags = fcntl(fd, F_GETFL);
705 if (flags < 0) {
706 APP_LOGE("dump Skill fcntl error : %{public}d", errno);
707 return;
708 }
709 uint uflags = static_cast<uint>(flags);
710 uflags &= O_ACCMODE;
711 if ((uflags == O_WRONLY) || (uflags == O_RDWR)) {
712 nlohmann::json jsonObject = *this;
713 std::string result;
714 result.append(prefix);
715 result.append(jsonObject.dump(Constants::DUMP_INDENT));
716 int ret = TEMP_FAILURE_RETRY(write(fd, result.c_str(), result.size()));
717 if (ret < 0) {
718 APP_LOGE("dump Abilityinfo write error : %{public}d", errno);
719 }
720 }
721 return;
722 }
723
from_json(const nlohmann::json & jsonObject,SkillUri & uri)724 void from_json(const nlohmann::json &jsonObject, SkillUri &uri)
725 {
726 const auto &jsonObjectEnd = jsonObject.end();
727 int32_t parseResult = ERR_OK;
728 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_SCHEME,
729 uri.scheme, false, parseResult);
730 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_HOST,
731 uri.host, false, parseResult);
732 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_PORT,
733 uri.port, false, parseResult);
734 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_PATH,
735 uri.path, false, parseResult);
736 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_PATHSTARTWITH,
737 uri.pathStartWith, false, parseResult);
738 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, BUNDLE_MODULE_PROFILE_KEY_PATHREGX,
739 uri.pathRegex, false, parseResult);
740 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_PATHREGEX,
741 uri.pathRegex, false, parseResult);
742 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_TYPE,
743 uri.type, false, parseResult);
744 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_UTD,
745 uri.utd, false, parseResult);
746 GetValueIfFindKey<int32_t>(jsonObject, jsonObjectEnd, JSON_KEY_MAXFILESUPPORTED,
747 uri.maxFileSupported, JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
748 BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, JSON_KEY_LINKFEATURE,
749 uri.linkFeature, false, parseResult);
750 }
751
from_json(const nlohmann::json & jsonObject,Skill & skill)752 void from_json(const nlohmann::json &jsonObject, Skill &skill)
753 {
754 const auto &jsonObjectEnd = jsonObject.end();
755 int32_t parseResult = ERR_OK;
756 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
757 jsonObjectEnd,
758 JSON_KEY_ACTIONS,
759 skill.actions,
760 JsonType::ARRAY,
761 false,
762 parseResult,
763 ArrayType::STRING);
764 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
765 jsonObjectEnd,
766 JSON_KEY_ENTITIES,
767 skill.entities,
768 JsonType::ARRAY,
769 false,
770 parseResult,
771 ArrayType::STRING);
772 GetValueIfFindKey<std::vector<SkillUri>>(jsonObject,
773 jsonObjectEnd,
774 JSON_KEY_URIS,
775 skill.uris,
776 JsonType::ARRAY,
777 false,
778 parseResult,
779 ArrayType::OBJECT);
780 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
781 jsonObjectEnd,
782 JSON_KEY_PERMISSIONS,
783 skill.permissions,
784 JsonType::ARRAY,
785 false,
786 parseResult,
787 ArrayType::STRING);
788 BMSJsonUtil::GetBoolValueIfFindKey(jsonObject,
789 jsonObjectEnd,
790 JSON_KEY_DOMAINVERIFY,
791 skill.domainVerify,
792 false,
793 parseResult);
794 }
795
to_json(nlohmann::json & jsonObject,const SkillUri & uri)796 void to_json(nlohmann::json &jsonObject, const SkillUri &uri)
797 {
798 jsonObject = nlohmann::json {
799 {JSON_KEY_SCHEME, uri.scheme},
800 {JSON_KEY_HOST, uri.host},
801 {JSON_KEY_PORT, uri.port},
802 {JSON_KEY_PATH, uri.path},
803 {JSON_KEY_PATHSTARTWITH, uri.pathStartWith},
804 {JSON_KEY_PATHREGEX, uri.pathRegex},
805 {JSON_KEY_TYPE, uri.type},
806 {JSON_KEY_UTD, uri.utd},
807 {JSON_KEY_MAXFILESUPPORTED, uri.maxFileSupported},
808 {JSON_KEY_LINKFEATURE, uri.linkFeature},
809 };
810 }
811
to_json(nlohmann::json & jsonObject,const Skill & skill)812 void to_json(nlohmann::json &jsonObject, const Skill &skill)
813 {
814 jsonObject = nlohmann::json {
815 {JSON_KEY_ACTIONS, skill.actions},
816 {JSON_KEY_ENTITIES, skill.entities},
817 {JSON_KEY_URIS, skill.uris},
818 {JSON_KEY_PERMISSIONS, skill.permissions},
819 {JSON_KEY_DOMAINVERIFY, skill.domainVerify}
820 };
821 }
822 } // namespace AppExecFwk
823 } // namespace OHOS
824