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 }