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