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 "parameter_parse.h" 17 18 #include "native_log.h" 19 #include "int_wrapper.h" 20 #include "double_wrapper.h" 21 #include "string_wrapper.h" 22 #include "bool_wrapper.h" 23 #include "long_wrapper.h" 24 #include "array_wrapper.h" 25 #include "want_params_wrapper.h" 26 #include "securec.h" 27 #include <cinttypes> 28 29 namespace OHOS::CommonEventManager { 30 const char *FD = "FD"; 31 const char *REMOTE_OBJECT = "RemoteObject"; 32 const char *TYPE_PROPERTY = "type"; 33 const char *VALUE_PROPERTY = "value"; 34 const int8_t I32_TYPE = 0; 35 const int8_t DOUBLE_TYPE = 1; 36 const int8_t STR_TYPE = 2; 37 const int8_t BOOL_TYPE = 3; 38 const int8_t FD_TYPE = 4; 39 const int8_t STR_PTR_TYPE = 5; 40 const int8_t I32_PTR_TYPE = 6; 41 const int8_t I64_PTR_TYPE = 7; 42 const int8_t BOOL_PTR_TYPE = 8; 43 const int8_t DOUBLE_PTR_TYPE = 9; 44 const int8_t FD_PTR_TYPE = 10; 45 const int32_t NONE_VALUE = 1; 46 using Want = OHOS::AAFwk::Want; 47 using WantParams = OHOS::AAFwk::WantParams; 48 charPtrToVector(char ** charPtr,int size,std::vector<std::string> & result)49 void charPtrToVector(char **charPtr, int size, std::vector<std::string> &result) 50 { 51 for (int i = 0; i < size; i++) { 52 result.push_back(std::string(charPtr[i])); 53 } 54 } 55 SetFdData(std::string key,int * value,WantParams & wantP)56 void SetFdData(std::string key, int *value, WantParams &wantP) 57 { 58 WantParams wp; 59 wp.SetParam(TYPE_PROPERTY, OHOS::AAFwk::String::Box(FD)); 60 wp.SetParam(VALUE_PROPERTY, OHOS::AAFwk::Integer::Box(*value)); 61 sptr<OHOS::AAFwk::IWantParams> pWantParams = OHOS::AAFwk::WantParamWrapper::Box(wp); 62 wantP.SetParam(key, pWantParams); 63 } 64 InnerSetWantParamsArrayString(const std::string & key,const std::vector<std::string> & value,AAFwk::WantParams & wantParams)65 bool InnerSetWantParamsArrayString( 66 const std::string &key, const std::vector<std::string> &value, AAFwk::WantParams &wantParams) 67 { 68 size_t size = value.size(); 69 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IString); 70 if (ao != nullptr) { 71 for (size_t i = 0; i < size; i++) { 72 ao->Set(i, AAFwk::String::Box(value[i])); 73 } 74 wantParams.SetParam(key, ao); 75 return true; 76 } else { 77 return false; 78 } 79 } 80 InnerSetWantParamsArrayInt(const std::string & key,const std::vector<int> & value,AAFwk::WantParams & wantParams)81 bool InnerSetWantParamsArrayInt(const std::string &key, const std::vector<int> &value, 82 AAFwk::WantParams &wantParams) 83 { 84 size_t size = value.size(); 85 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IInteger); 86 if (ao != nullptr) { 87 for (size_t i = 0; i < size; i++) { 88 ao->Set(i, AAFwk::Integer::Box(value[i])); 89 } 90 wantParams.SetParam(key, ao); 91 return true; 92 } else { 93 return false; 94 } 95 } 96 InnerSetWantParamsArrayLong(const std::string & key,const std::vector<long> & value,AAFwk::WantParams & wantParams)97 bool InnerSetWantParamsArrayLong(const std::string &key, const std::vector<long> &value, 98 AAFwk::WantParams &wantParams) 99 { 100 size_t size = value.size(); 101 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_ILong); 102 if (ao != nullptr) { 103 for (size_t i = 0; i < size; i++) { 104 ao->Set(i, AAFwk::Long::Box(value[i])); 105 } 106 wantParams.SetParam(key, ao); 107 return true; 108 } else { 109 return false; 110 } 111 } 112 InnerSetWantParamsArrayBool(const std::string & key,const std::vector<bool> & value,AAFwk::WantParams & wantParams)113 bool InnerSetWantParamsArrayBool(const std::string &key, const std::vector<bool> &value, 114 AAFwk::WantParams &wantParams) 115 { 116 size_t size = value.size(); 117 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IBoolean); 118 if (ao != nullptr) { 119 for (size_t i = 0; i < size; i++) { 120 ao->Set(i, AAFwk::Boolean::Box(value[i])); 121 } 122 wantParams.SetParam(key, ao); 123 return true; 124 } else { 125 return false; 126 } 127 } 128 InnerSetWantParamsArrayDouble(const std::string & key,const std::vector<double> & value,AAFwk::WantParams & wantParams)129 bool InnerSetWantParamsArrayDouble( 130 const std::string &key, const std::vector<double> &value, AAFwk::WantParams &wantParams) 131 { 132 size_t size = value.size(); 133 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IDouble); 134 if (ao != nullptr) { 135 for (size_t i = 0; i < size; i++) { 136 ao->Set(i, AAFwk::Double::Box(value[i])); 137 } 138 wantParams.SetParam(key, ao); 139 return true; 140 } else { 141 return false; 142 } 143 } 144 InnerSetWantParamsArrayFD(CParameters * head,int64_t size,AAFwk::WantParams & wantParams)145 void InnerSetWantParamsArrayFD(CParameters* head, int64_t size, AAFwk::WantParams &wantParams) 146 { 147 sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IWantParams); 148 if (ao != nullptr) { 149 for (size_t i = 0; i < static_cast<size_t>(size); i++) { 150 WantParams wp; 151 SetFdData(std::string(head->key), static_cast<int *>(head->value) + i, wp); 152 wp.DumpInfo(0); 153 ao->Set(i, OHOS::AAFwk::WantParamWrapper::Box(wp)); 154 } 155 wantParams.SetParam(std::string(head->key), ao); 156 } 157 return; 158 } 159 SetDataParameters(CArrParameters parameters,WantParams & wantP)160 void SetDataParameters(CArrParameters parameters, WantParams &wantP) 161 { 162 for (int i = 0; i < parameters.size; i++) { 163 auto head = parameters.head + i; 164 auto key = std::string(head->key); 165 if (head->valueType == I32_TYPE) { // int32_t 166 wantP.SetParam(key, OHOS::AAFwk::Integer::Box(*static_cast<int32_t *>(head->value))); 167 } else if (head->valueType == DOUBLE_TYPE) { // double 168 wantP.SetParam(key, OHOS::AAFwk::Double::Box(*static_cast<double *>(head->value))); 169 } else if (head->valueType == STR_TYPE) { // std::string 170 wantP.SetParam(key, OHOS::AAFwk::String::Box(std::string(static_cast<char *>(head->value)))); 171 } else if (head->valueType == BOOL_TYPE) { // bool 172 wantP.SetParam(key, OHOS::AAFwk::Boolean::Box(*static_cast<bool *>(head->value))); 173 } else if (head->valueType == FD_TYPE) { // "FD" 174 SetFdData(key, static_cast<int *>(head->value), wantP); 175 } else if (head->valueType == STR_PTR_TYPE) { // char** 176 char **strPtr = static_cast<char **>(head->value); 177 std::vector<std::string> strVec; 178 charPtrToVector(strPtr, head->size, strVec); 179 InnerSetWantParamsArrayString(key, strVec, wantP); 180 } else if (head->valueType == I32_PTR_TYPE) { // int32_t* 181 int *intArr = static_cast<int *>(head->value); 182 std::vector<int> intVec(intArr, intArr + head->size); 183 InnerSetWantParamsArrayInt(key, intVec, wantP); 184 } else if (head->valueType == I64_PTR_TYPE) { // int64_t* 185 long *longArr = static_cast<long *>(head->value); 186 std::vector<long> longVec(longArr, longArr + head->size); 187 InnerSetWantParamsArrayLong(key, longVec, wantP); 188 } else if (head->valueType == BOOL_PTR_TYPE) { // bool* 189 bool *boolArr = static_cast<bool *>(head->value); 190 std::vector<bool> boolVec(boolArr, boolArr + head->size); 191 InnerSetWantParamsArrayBool(key, boolVec, wantP); 192 } else if (head->valueType == DOUBLE_PTR_TYPE) { // double* 193 double *doubleArr = static_cast<double *>(head->value); 194 std::vector<double> doubleVec(doubleArr, doubleArr + head->size); 195 InnerSetWantParamsArrayDouble(key, doubleVec, wantP); 196 } else if (head->valueType == FD_PTR_TYPE) { // FD* 197 InnerSetWantParamsArrayFD(head, head->size, wantP); 198 } else { 199 LOGE("Wrong type!"); 200 } 201 } 202 } 203 MallocCString(const std::string & origin)204 char *MallocCString(const std::string &origin) 205 { 206 if (origin.empty()) { 207 return nullptr; 208 } 209 auto len = origin.length() + 1; 210 char *res = static_cast<char *>(malloc(sizeof(char) * len)); 211 if (res == nullptr) { 212 return nullptr; 213 } 214 return std::char_traits<char>::copy(res, origin.c_str(), len); 215 } 216 MallocCString(const std::string & origin,int32_t & code)217 char *MallocCString(const std::string &origin, int32_t &code) 218 { 219 if (origin.empty() || code != NO_ERROR) { 220 return nullptr; 221 } 222 auto len = origin.length() + 1; 223 char *res = static_cast<char *>(malloc(sizeof(char) * len)); 224 if (res == nullptr) { 225 code = ERR_NO_MEMORY; 226 return nullptr; 227 } 228 return std::char_traits<char>::copy(res, origin.c_str(), len); 229 } 230 231 // WantParameters -> CArrParameters InnerWrapWantParamsString(WantParams & wantParams,CParameters * p)232 int32_t InnerWrapWantParamsString(WantParams &wantParams, CParameters *p) 233 { 234 auto value = wantParams.GetParam(p->key); 235 AAFwk::IString *ao = AAFwk::IString::Query(value); 236 if (ao == nullptr) { 237 LOGE("No value"); 238 return NONE_VALUE; 239 } 240 std::string natValue = OHOS::AAFwk::String::Unbox(ao); 241 p->value = MallocCString(natValue); 242 p->size = static_cast<int64_t>(natValue.length()) + 1; 243 p->valueType = STR_TYPE; 244 return NO_ERROR; 245 } 246 247 template <class TBase, class T, class NativeT> InnerWrapWantParamsT(WantParams & wantParams,CParameters * p)248 int32_t InnerWrapWantParamsT(WantParams &wantParams, CParameters *p) 249 { 250 auto value = wantParams.GetParam(p->key); 251 TBase *ao = TBase::Query(value); 252 if (ao == nullptr) { 253 LOGE("No value"); 254 return NONE_VALUE; 255 } 256 NativeT natValue = T::Unbox(ao); 257 NativeT *ptr = static_cast<NativeT *>(malloc(sizeof(NativeT))); 258 if (ptr == nullptr) { 259 return ERR_NO_MEMORY; 260 } 261 *ptr = natValue; 262 p->value = static_cast<void*>(ptr); 263 p->size = sizeof(NativeT); 264 return NO_ERROR; 265 } 266 InnerWrapWantParamsArrayString(sptr<AAFwk::IArray> & ao,CParameters * p)267 int32_t InnerWrapWantParamsArrayString(sptr<AAFwk::IArray> &ao, CParameters *p) 268 { 269 long size = 0; 270 if (ao->GetLength(size) != ERR_OK) { 271 LOGE("fail to get length"); 272 return ERR_CES_FAILED; 273 } 274 if (size == 0) { 275 return ERR_CES_FAILED; 276 } 277 char **arrP = static_cast<char **>(malloc(sizeof(char *) * size)); 278 if (arrP == nullptr) { 279 LOGE("fail to malloc"); 280 return ERR_NO_MEMORY; 281 } 282 for (long i = 0; i < size; i++) { 283 sptr<AAFwk::IInterface> iface = nullptr; 284 if (ao->Get(i, iface) == ERR_OK) { 285 AAFwk::IString *iValue = AAFwk::IString::Query(iface); 286 if (iValue != nullptr) { 287 auto val = AAFwk::String::Unbox(iValue); 288 arrP[i] = MallocCString(val); 289 } 290 } 291 } 292 p->size = size; 293 p->value = static_cast<void *>(arrP); 294 return NO_ERROR; 295 } 296 ClearParametersPtr(CParameters ** ptr,int count,bool isKey)297 void ClearParametersPtr(CParameters **ptr, int count, bool isKey) 298 { 299 CParameters *p = *ptr; 300 for (int i = 0; i < count; i++) { 301 free(p[i].key); 302 free(p[i].value); 303 p[i].key = nullptr; 304 p[i].value = nullptr; 305 } 306 if (!isKey) { 307 free(p[count].key); 308 p[count].key = nullptr; 309 } 310 free(*ptr); 311 *ptr = nullptr; 312 } 313 314 template <class TBase, class T, class NativeT> InnerWrapWantParamsArrayT(sptr<AAFwk::IArray> & ao,CParameters * p)315 int32_t InnerWrapWantParamsArrayT(sptr<AAFwk::IArray> &ao, CParameters *p) 316 { 317 long size = 0; 318 if (ao->GetLength(size) != ERR_OK) { 319 LOGE("fail to get length"); 320 return ERR_CES_FAILED; 321 } 322 if (size == 0) { 323 return ERR_CES_FAILED; 324 } 325 NativeT *arrP = static_cast<NativeT *>(malloc(sizeof(NativeT) * size)); 326 if (arrP == nullptr) { 327 LOGE("fail to malloc"); 328 return ERR_NO_MEMORY; 329 } 330 for (long i = 0; i < size; i++) { 331 sptr<AAFwk::IInterface> iface = nullptr; 332 if (ao->Get(i, iface) == ERR_OK) { 333 TBase *iValue = TBase::Query(iface); 334 if (iValue != nullptr) { 335 arrP[i] = T::Unbox(iValue); 336 } 337 } 338 } 339 p->size = size; 340 p->value = static_cast<void *>(arrP); 341 return NO_ERROR; 342 } 343 GetFDValue(WantParams & wantParams,std::string key,int * ptr)344 int32_t GetFDValue(WantParams &wantParams, std::string key, int *ptr) 345 { 346 auto value = wantParams.GetParam(key); 347 AAFwk::IWantParams *o = AAFwk::IWantParams::Query(value); 348 if (o == nullptr) { 349 return NONE_VALUE; 350 } 351 AAFwk::WantParams wp = AAFwk::WantParamWrapper::Unbox(o); 352 value = wp.GetParam(VALUE_PROPERTY); 353 AAFwk::IInteger *ao = AAFwk::IInteger::Query(value); 354 if (ao == nullptr) { 355 LOGE("No value"); 356 return NONE_VALUE; 357 } 358 *ptr = OHOS::AAFwk::Integer::Unbox(ao); 359 return NO_ERROR; 360 } 361 InnerWrapWantParamsFd(WantParams & wantParams,CParameters * p)362 int32_t InnerWrapWantParamsFd(WantParams &wantParams, CParameters *p) 363 { 364 int *ptr = static_cast<int *>(malloc(sizeof(int))); 365 if (ptr == nullptr) { 366 return ERR_NO_MEMORY; 367 } 368 int error = GetFDValue(wantParams, std::string(p->key), ptr); 369 if (error != NO_ERROR) { 370 free(ptr); 371 return error; 372 } 373 p->value = static_cast<void*>(ptr); 374 p->size = sizeof(int32_t); 375 p->valueType = FD_TYPE; 376 return NO_ERROR; 377 } 378 InnerWrapWantParamsArrayFd(sptr<AAFwk::IArray> & ao,CParameters * p)379 int32_t InnerWrapWantParamsArrayFd(sptr<AAFwk::IArray> &ao, CParameters *p) 380 { 381 long size = 0; 382 if (ao->GetLength(size) != ERR_OK) { 383 LOGE("fail to get length"); 384 return ERR_CES_FAILED; 385 } 386 if (size == 0) { 387 return ERR_CES_FAILED; 388 } 389 int *arrP = static_cast<int *>(malloc(sizeof(int) * size)); 390 if (arrP == nullptr) { 391 LOGE("fail to malloc"); 392 return ERR_NO_MEMORY; 393 } 394 for (long i = 0; i < size; i++) { 395 sptr<AAFwk::IInterface> iface = nullptr; 396 if (ao->Get(i, iface) == ERR_OK) { 397 AAFwk::IWantParams *iValue = AAFwk::IWantParams::Query(iface); 398 if (iValue == nullptr) { 399 free(arrP); 400 return ERR_CES_FAILED; 401 } 402 WantParams wantP = AAFwk::WantParamWrapper::Unbox(iValue); 403 int ret = GetFDValue(wantP, std::string(p->key), arrP + i); 404 if (ret != NO_ERROR) { 405 free(arrP); 406 return ret; 407 } 408 } 409 } 410 p->size = size; 411 p->value = arrP; 412 p->valueType = FD_PTR_TYPE; 413 return NO_ERROR; 414 } 415 InnerWrapWantParamsArray(WantParams & wantParams,sptr<AAFwk::IArray> & ao,CParameters * p)416 int32_t InnerWrapWantParamsArray(WantParams &wantParams, sptr<AAFwk::IArray> &ao, CParameters *p) 417 { 418 LOGI("%{public}s called. key=%{public}s", __func__, p->key); 419 if (AAFwk::Array::IsStringArray(ao)) { 420 p->valueType = STR_PTR_TYPE; 421 return InnerWrapWantParamsArrayString(ao, p); 422 } else if (AAFwk::Array::IsBooleanArray(ao)) { 423 p->valueType = BOOL_PTR_TYPE; 424 return InnerWrapWantParamsArrayT<AAFwk::IBoolean, AAFwk::Boolean, bool>(ao, p); 425 } else if (AAFwk::Array::IsIntegerArray(ao)) { 426 p->valueType = I32_PTR_TYPE; 427 return InnerWrapWantParamsArrayT<AAFwk::IInteger, AAFwk::Integer, int>(ao, p); 428 } else if (AAFwk::Array::IsLongArray(ao)) { 429 p->valueType = I64_PTR_TYPE; 430 return InnerWrapWantParamsArrayT<AAFwk::ILong, AAFwk::Long, int64_t>(ao, p); 431 } else if (AAFwk::Array::IsDoubleArray(ao)) { 432 p->valueType = DOUBLE_PTR_TYPE; 433 return InnerWrapWantParamsArrayT<AAFwk::IDouble, AAFwk::Double, double>(ao, p); 434 } else { 435 p->valueType = FD_PTR_TYPE; 436 return InnerWrapWantParamsArrayFd(ao, p); 437 } 438 } 439 ParseParameters(Want & want,CCommonEventData & cData,int32_t & code)440 void ParseParameters(Want &want, CCommonEventData &cData, int32_t &code) 441 { 442 if (code != NO_ERROR) { 443 return; 444 } 445 WantParams wantP = want.GetParams(); 446 std::map<std::string, sptr<OHOS::AAFwk::IInterface>> paramsMap = wantP.GetParams(); 447 int count = 0; 448 auto size = static_cast<int64_t>(paramsMap.size()); 449 LOGD("paramsMap size = %{public}" PRId64, size); 450 if (size == 0) { 451 return; 452 } 453 cData.parameters.head = static_cast<CParameters *>(malloc(sizeof(CParameters) * size)); 454 if (cData.parameters.head == nullptr) { 455 return; 456 } 457 cData.parameters.size = size; 458 for (auto iter = paramsMap.begin(); iter != paramsMap.end(); iter++) { 459 auto ptr = cData.parameters.head + count; 460 ptr->key = MallocCString(iter->first); 461 if (ptr->key == nullptr) { 462 code = ERR_NO_MEMORY; 463 return ClearParametersPtr(&cData.parameters.head, count, true); 464 } 465 ptr->value = nullptr; 466 ptr->size = 0; 467 if (AAFwk::IString::Query(iter->second) != nullptr) { 468 code = InnerWrapWantParamsString(wantP, ptr); 469 } else if (AAFwk::IBoolean::Query(iter->second) != nullptr) { 470 ptr->valueType = BOOL_TYPE; 471 code = InnerWrapWantParamsT<AAFwk::IBoolean, AAFwk::Boolean, bool>(wantP, ptr); 472 } else if (AAFwk::IInteger::Query(iter->second) != nullptr) { 473 ptr->valueType = I32_TYPE; 474 code = InnerWrapWantParamsT<AAFwk::IInteger, AAFwk::Integer, int>(wantP, ptr); 475 } else if (AAFwk::IDouble::Query(iter->second) != nullptr) { 476 ptr->valueType = DOUBLE_TYPE; 477 code = InnerWrapWantParamsT<AAFwk::IDouble, AAFwk::Double, double>(wantP, ptr); 478 } else if (AAFwk::IWantParams::Query(iter->second) != nullptr) { 479 code = InnerWrapWantParamsFd(wantP, ptr); 480 } else if (AAFwk::IArray::Query(iter->second) != nullptr) { 481 AAFwk::IArray *ao = AAFwk::IArray::Query(iter->second); 482 sptr<AAFwk::IArray> array(ao); 483 code = InnerWrapWantParamsArray(wantP, array, ptr); 484 } 485 if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) { 486 return ClearParametersPtr(&cData.parameters.head, count, true); 487 } 488 count++; 489 } 490 } 491 FreeCCommonEventDataCharPtr(CCommonEventData & cData)492 void FreeCCommonEventDataCharPtr(CCommonEventData &cData) 493 { 494 free(cData.data); 495 free(cData.event); 496 free(cData.bundleName); 497 cData.data = nullptr; 498 cData.event = nullptr; 499 cData.bundleName = nullptr; 500 } 501 GetCommonEventData(const CommonEventData & data,CCommonEventData & cData)502 int32_t GetCommonEventData(const CommonEventData &data, CCommonEventData &cData) 503 { 504 auto want = data.GetWant(); 505 cData.code = data.GetCode(); 506 int32_t code = NO_ERROR; 507 cData.data = MallocCString(data.GetData(), code); 508 cData.event = MallocCString(want.GetAction(), code); 509 cData.bundleName = MallocCString(want.GetBundle(), code); 510 ParseParameters(want, cData, code); 511 if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) { 512 FreeCCommonEventDataCharPtr(cData); 513 } 514 return code; 515 } 516 }