1 /* 2 * Copyright (c) 2020 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 "want_utils.h" 17 #include "element_name_utils.h" 18 19 #include <securec.h> 20 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER 21 #include <string> 22 #include "ipc_skeleton.h" 23 #endif 24 25 #include "log.h" 26 #include "utils.h" 27 28 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER 29 using UriKeyType = enum { 30 BEGIN, 31 DEVICE, 32 BUNDLE, 33 ABILITY, 34 END, 35 }; 36 37 using UriProperties = struct { 38 const char *key; /* key of uri property */ 39 uint8_t keyLen; /* key length of uri property */ 40 UriKeyType type; /* key type of uri property */ 41 }; 42 43 const static UriProperties URI_PROPERTIES[] = { 44 { "#Want", 5, BEGIN }, 45 { "device=", 7, DEVICE }, 46 { "bundle=", 7, BUNDLE }, 47 { "ability=", 8, ABILITY }, 48 { "end", 3, END }, 49 }; 50 51 constexpr static char URI_SEPARATOR = ';'; 52 constexpr static int VALUE_NULL = 0; 53 constexpr static int VALUE_OBJECT = 1; 54 constexpr static int DATA_LENGTH = 2048; 55 #endif 56 57 constexpr uint8_t INT_VALUE_TYPE = 6; 58 constexpr uint8_t STRING_VALUE_TYPE = 13; 59 constexpr uint8_t KEY_VALUE_PAIR_TYPE = 97; 60 61 void ClearWant(Want *want) 62 { 63 if (want == nullptr) { 64 return; 65 } 66 67 ClearElement(want->element); 68 AdapterFree(want->element); 69 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER 70 AdapterFree(want->sid); 71 #endif 72 AdapterFree(want->appPath); 73 AdapterFree(want->data); 74 #ifndef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER 75 AdapterFree(want->actions); 76 AdapterFree(want->entities); 77 #endif 78 } 79 80 bool SetWantElement(Want *want, ElementName element) 81 { 82 if (want == nullptr) { 83 return false; 84 } 85 86 ClearElement(want->element); 87 AdapterFree(want->element); 88 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName))); 89 if (want->element == nullptr) { 90 return false; 91 } 92 want->element->deviceId = OHOS::Utils::Strdup(element.deviceId); 93 want->element->bundleName = OHOS::Utils::Strdup(element.bundleName); 94 want->element->abilityName = OHOS::Utils::Strdup(element.abilityName); 95 return true; 96 } 97 98 Tlv *EncapTlv(uint8_t type, uint8_t length, const void *value, uint8_t valueLen) 99 { 100 void *entity = nullptr; 101 102 // Tlv header can only has 2 bytes. 103 uint8_t totalLen = valueLen + 2; 104 entity = AdapterMalloc(totalLen); 105 if (entity == nullptr) { 106 return nullptr; 107 } 108 109 if (memcpy_s((unsigned char *)entity, totalLen, &type, 1) != 0 || 110 memcpy_s((unsigned char *)entity + 1, totalLen - 1, &length, 1) != 0 || 111 memcpy_s((unsigned char *)entity + 2, valueLen, value, valueLen) != 0) { 112 AdapterFree(entity); 113 return nullptr; 114 } 115 116 Tlv *newTlv = reinterpret_cast<Tlv *>(AdapterMalloc(sizeof(Tlv))); 117 if (newTlv == nullptr) { 118 AdapterFree(entity); 119 return nullptr; 120 } 121 122 newTlv->type = type; 123 newTlv->entity = entity; 124 newTlv->totalLen = totalLen; 125 return newTlv; 126 } 127 128 void FreeTlvStruct(Tlv *tlv) 129 { 130 AdapterFree(tlv->entity); 131 AdapterFree(tlv); 132 } 133 134 Tlv *CombineKeyValueTlv(Tlv *keyTlv, Tlv *valueTlv) 135 { 136 uint8_t newTlvValueLen = keyTlv->totalLen + valueTlv->totalLen; 137 void *newTlvValue = AdapterMalloc(newTlvValueLen); 138 if (newTlvValue == nullptr) { 139 return nullptr; 140 } 141 if (memcpy_s((unsigned char *)newTlvValue, keyTlv->totalLen, keyTlv->entity, keyTlv->totalLen) != 0 || 142 memcpy_s((unsigned char *)newTlvValue + keyTlv->totalLen, valueTlv->totalLen, 143 valueTlv->entity, valueTlv->totalLen) != 0) { 144 AdapterFree(newTlvValue); 145 return nullptr; 146 } 147 148 Tlv *newTlv = EncapTlv(KEY_VALUE_PAIR_TYPE, newTlvValueLen, newTlvValue, newTlvValueLen); 149 AdapterFree(newTlvValue); 150 return newTlv; 151 } 152 153 bool UpdateWantData(Want *want, Tlv *tlv) 154 { 155 bool result = false; 156 if (want->data != nullptr) { 157 void *newWantData = AdapterMalloc(tlv->totalLen + want->dataLength); 158 if (newWantData == nullptr) { 159 return result; 160 } 161 if (memcpy_s(newWantData, want->dataLength, want->data, want->dataLength) != 0 || 162 memcpy_s((unsigned char*)newWantData + want->dataLength, tlv->totalLen, tlv->entity, tlv->totalLen) != 0) { 163 AdapterFree(newWantData); 164 return result; 165 } 166 SetWantData(want, newWantData, tlv->totalLen + want->dataLength); 167 AdapterFree(newWantData); 168 result = true; 169 } else { 170 SetWantData(want, tlv->entity, tlv->totalLen); 171 result = true; 172 } 173 return result; 174 } 175 176 bool SetIntParam(Want *want, const char *key, uint8_t keyLen, int32_t value) 177 { 178 bool result = false; 179 if (keyLen <= 0) { 180 return result; 181 } 182 183 Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen); 184 if (keyTlv == nullptr) { 185 return result; 186 } 187 if (value < 0) { 188 HILOG_ERROR(HILOG_MODULE_APP, "SetIntParam value should be positive"); 189 FreeTlvStruct(keyTlv); 190 return result; 191 } 192 int intBufferNumber = 4; 193 unsigned char intBuffer[4] = {0}; 194 for (int i = 0; i < intBufferNumber; i++) { 195 intBuffer[i] = value >> (8 * (3- i)); 196 } 197 Tlv *valueTlv = EncapTlv(INT_VALUE_TYPE, sizeof(int), (void *)intBuffer, sizeof(int)); 198 if (valueTlv == nullptr) { 199 FreeTlvStruct(keyTlv); 200 return result; 201 } 202 Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv); 203 FreeTlvStruct(keyTlv); 204 FreeTlvStruct(valueTlv); 205 if (newTlv == nullptr) { 206 return result; 207 } 208 if (UpdateWantData(want, newTlv)) { 209 result = true; 210 } 211 AdapterFree(newTlv); 212 return result; 213 } 214 215 bool SetStrParam(Want *want, const char *key, uint8_t keyLen, const char *value, uint8_t valueLen) 216 { 217 bool result = false; 218 if (keyLen <= 0 || valueLen <= 0) { 219 return result; 220 } 221 222 Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen); 223 if (keyTlv == nullptr) { 224 return result; 225 } 226 227 Tlv *valueTlv = EncapTlv(STRING_VALUE_TYPE, valueLen, (void *)value, valueLen); 228 if (valueTlv == nullptr) { 229 FreeTlvStruct(keyTlv); 230 return result; 231 } 232 Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv); 233 FreeTlvStruct(keyTlv); 234 FreeTlvStruct(valueTlv); 235 if (newTlv == nullptr) { 236 return result; 237 } 238 if (UpdateWantData(want, newTlv)) { 239 result = true; 240 } 241 AdapterFree(newTlv); 242 return result; 243 } 244 245 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER 246 bool SetWantSvcIdentity(Want *want, SvcIdentity sid) 247 { 248 if (want == nullptr) { 249 return false; 250 } 251 252 AdapterFree(want->sid); 253 want->sid = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity))); 254 if (want->sid == nullptr) { 255 return false; 256 } 257 if (memcpy_s(want->sid, sizeof(SvcIdentity), &sid, sizeof(SvcIdentity)) != EOK) { 258 AdapterFree(want->sid); 259 return false; 260 } 261 262 return true; 263 } 264 #endif 265 266 bool SetWantData(Want *want, const void *data, uint16_t dataLength) 267 { 268 if (want == nullptr) { 269 return false; 270 } 271 272 AdapterFree(want->data); 273 want->data = OHOS::Utils::Memdup(data, dataLength); 274 if (want->data == nullptr) { 275 want->dataLength = 0; 276 return false; 277 } 278 279 want->dataLength = dataLength; 280 return true; 281 } 282 283 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER 284 bool SerializeWant(IpcIo *io, const Want *want) 285 { 286 if ((io == nullptr) || (want == nullptr) || (want->dataLength > DATA_LENGTH)) { 287 return false; 288 } 289 290 if (want->element == nullptr) { 291 WriteInt32(io, VALUE_NULL); 292 } else { 293 WriteInt32(io, VALUE_OBJECT); 294 if (!SerializeElement(io, want->element)) { 295 return false; 296 } 297 } 298 WriteInt32(io, want->dataLength); 299 if (want->dataLength > 0) { 300 WriteBuffer(io, want->data, want->dataLength); 301 } 302 if (want->sid == nullptr) { 303 WriteInt32(io, VALUE_NULL); 304 } else { 305 WriteInt32(io, VALUE_OBJECT); 306 bool ret = WriteRemoteObject(io, want->sid); 307 if (!ret) { 308 return false; 309 } 310 } 311 312 return true; 313 } 314 315 bool DeserializeWant(Want *want, IpcIo *io) 316 { 317 if ((want == nullptr) || (io == nullptr)) { 318 return false; 319 } 320 321 int ret = 0; 322 ReadInt32(io, &ret); 323 if (ret == VALUE_OBJECT) { 324 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName))); 325 if (want->element == nullptr || 326 memset_s(want->element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK || 327 !DeserializeElement(want->element, io)) { 328 AdapterFree(want->element); 329 return false; 330 } 331 } 332 uint32_t size = 0; 333 ReadUint32(io, &size); 334 if (size > 0) { 335 void *data = (void*)ReadBuffer(io, (size_t)size); 336 if (!SetWantData(want, data, size)) { 337 ClearWant(want); 338 return false; 339 } 340 } 341 ReadInt32(io, &ret); 342 if (ret == VALUE_OBJECT) { 343 SvcIdentity svc; 344 bool ret = ReadRemoteObject(io, &svc); 345 if (!ret || !SetWantSvcIdentity(want, svc)) { 346 ClearWant(want); 347 return false; 348 } 349 } 350 351 return true; 352 } 353 354 Want *WantParseUri(const char *uri) 355 { 356 if (uri == nullptr) { 357 return nullptr; 358 } 359 char *parseUri = OHOS::Utils::Strdup(uri); 360 if (parseUri == nullptr) { 361 return nullptr; 362 } 363 ElementName element = { nullptr, nullptr, nullptr }; 364 char *beginIndex = parseUri; 365 for (auto property : URI_PROPERTIES) { 366 if (strstr(beginIndex, property.key) != beginIndex) { 367 AdapterFree(parseUri); 368 return nullptr; 369 } 370 if (property.type == END) { 371 break; 372 } 373 char *endIndex = strchr(beginIndex, URI_SEPARATOR); 374 if ((endIndex == nullptr) || (endIndex <= beginIndex)) { 375 AdapterFree(parseUri); 376 return nullptr; 377 } 378 *endIndex = '\0'; 379 beginIndex += property.keyLen; 380 switch (property.type) { 381 case DEVICE: { 382 SetElementDeviceID(&element, beginIndex); 383 break; 384 } 385 case BUNDLE: { 386 SetElementBundleName(&element, beginIndex); 387 break; 388 } 389 case ABILITY: { 390 SetElementAbilityName(&element, beginIndex); 391 break; 392 } 393 default: { 394 break; 395 } 396 } 397 beginIndex = endIndex + 1; 398 } 399 AdapterFree(parseUri); 400 Want *want = new Want(); 401 if ((memset_s(want, sizeof(Want), 0, sizeof(Want)) != EOK) || !SetWantElement(want, element)) { 402 ClearElement(&element); 403 delete want; 404 return nullptr; 405 } 406 ClearElement(&element); 407 return want; 408 } 409 410 const char *WantToUri(Want want) 411 { 412 std::string uriString; 413 414 for (auto property : URI_PROPERTIES) { 415 uriString += property.key; 416 switch (property.type) { 417 case BEGIN: { 418 uriString += URI_SEPARATOR; 419 break; 420 } 421 case DEVICE: { 422 if ((want.element != nullptr) && (want.element->deviceId != nullptr)) { 423 uriString += want.element->deviceId; 424 } 425 uriString += URI_SEPARATOR; 426 break; 427 } 428 case BUNDLE: { 429 if ((want.element != nullptr) && (want.element->bundleName != nullptr)) { 430 uriString += want.element->bundleName; 431 } 432 uriString += URI_SEPARATOR; 433 break; 434 } 435 case ABILITY: { 436 if ((want.element != nullptr) && (want.element->abilityName != nullptr)) { 437 uriString += want.element->abilityName; 438 } 439 uriString += URI_SEPARATOR; 440 break; 441 } 442 default: { 443 break; 444 } 445 } 446 } 447 448 uint16_t len = uriString.size(); 449 char *uri = reinterpret_cast<char *>(AdapterMalloc(len + 1)); 450 if (uri == nullptr) { 451 return nullptr; 452 } 453 if (strncpy_s(uri, len + 1, uriString.c_str(), len) < 0) { 454 AdapterFree(uri); 455 return nullptr; 456 } 457 458 return uri; 459 } 460 #endif 461