• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ipc_cparcel.h"
17 
18 #include <securec.h>
19 
20 #include "ipc_debug.h"
21 #include "ipc_error_code.h"
22 #include "ipc_inner_object.h"
23 #include "ipc_internal_utils.h"
24 #include "log_tags.h"
25 #include "message_parcel.h"
26 
27 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, OHOS::LOG_ID_IPC_CAPI, "OHIPCParcel" };
28 
OH_IPCParcel_Create(void)29 OHIPCParcel* OH_IPCParcel_Create(void)
30 {
31     OHOS::MessageParcel *msgParcel = new (std::nothrow) OHOS::MessageParcel();
32     if (msgParcel == nullptr) {
33         ZLOGE(LOG_LABEL, "message parcel is null!");
34         return nullptr;
35     }
36     OHIPCParcel *parcel = new (std::nothrow) OHIPCParcel();
37     if (parcel == nullptr) {
38         ZLOGE(LOG_LABEL, "ipc parcel is null!");
39         delete msgParcel;
40         return nullptr;
41     }
42     parcel->msgParcel = msgParcel;
43     return parcel;
44 }
45 
OH_IPCParcel_Destroy(OHIPCParcel * parcel)46 void OH_IPCParcel_Destroy(OHIPCParcel *parcel)
47 {
48     if (parcel != nullptr) {
49         if (parcel->msgParcel != nullptr) {
50             delete parcel->msgParcel;
51             parcel->msgParcel = nullptr;
52         }
53         delete parcel;
54     }
55 }
56 
57 template <typename T, typename U>
SetParcelProperty(OHIPCParcel * parcel,T value,bool (OHOS::MessageParcel::* SetProperty)(U value))58 static int SetParcelProperty(OHIPCParcel *parcel, T value, bool (OHOS::MessageParcel::*SetProperty)(U value))
59 {
60     if (!IsIPCParcelValid(parcel, __func__)) {
61         return OH_IPC_CHECK_PARAM_ERROR;
62     }
63     return (parcel->msgParcel->*SetProperty)(static_cast<U>(value)) ? OH_IPC_SUCCESS : OH_IPC_INNER_ERROR;
64 }
65 
66 template <typename T, typename U>
GetParcelPropertyConst(const OHIPCParcel * parcel,U (OHOS::MessageParcel::* GetProperty)()const)67 static T GetParcelPropertyConst(const OHIPCParcel *parcel, U (OHOS::MessageParcel::*GetProperty)() const)
68 {
69     if (!IsIPCParcelValid(parcel, __func__)) {
70         return -1;
71     }
72     return static_cast<T>((parcel->msgParcel->*GetProperty)());
73 }
74 
75 template <typename T, typename U>
GetParcelProperty(const OHIPCParcel * parcel,U (OHOS::MessageParcel::* GetProperty)())76 static T GetParcelProperty(const OHIPCParcel *parcel, U (OHOS::MessageParcel::*GetProperty)())
77 {
78     if (!IsIPCParcelValid(parcel, __func__)) {
79         return -1;
80     }
81     return static_cast<T>((parcel->msgParcel->*GetProperty)());
82 }
83 
OH_IPCParcel_GetDataSize(const OHIPCParcel * parcel)84 int OH_IPCParcel_GetDataSize(const OHIPCParcel *parcel)
85 {
86     return GetParcelPropertyConst<int, size_t>(parcel, &OHOS::MessageParcel::GetDataSize);
87 }
88 
OH_IPCParcel_GetWritableBytes(const OHIPCParcel * parcel)89 int OH_IPCParcel_GetWritableBytes(const OHIPCParcel *parcel)
90 {
91     return GetParcelPropertyConst<int, size_t>(parcel, &OHOS::MessageParcel::GetWritableBytes);
92 }
93 
OH_IPCParcel_GetReadableBytes(const OHIPCParcel * parcel)94 int OH_IPCParcel_GetReadableBytes(const OHIPCParcel *parcel)
95 {
96     return GetParcelPropertyConst<int, size_t>(parcel, &OHOS::MessageParcel::GetReadableBytes);
97 }
98 
OH_IPCParcel_GetReadPosition(const OHIPCParcel * parcel)99 int OH_IPCParcel_GetReadPosition(const OHIPCParcel *parcel)
100 {
101     return GetParcelProperty<int, size_t>(parcel, &OHOS::MessageParcel::GetReadPosition);
102 }
103 
OH_IPCParcel_GetWritePosition(const OHIPCParcel * parcel)104 int OH_IPCParcel_GetWritePosition(const OHIPCParcel *parcel)
105 {
106     return GetParcelProperty<int, size_t>(parcel, &OHOS::MessageParcel::GetWritePosition);
107 }
108 
OH_IPCParcel_RewindReadPosition(OHIPCParcel * parcel,uint32_t newReadPos)109 int OH_IPCParcel_RewindReadPosition(OHIPCParcel *parcel, uint32_t newReadPos)
110 {
111     return SetParcelProperty<uint32_t, size_t>(parcel, newReadPos, &OHOS::MessageParcel::RewindRead);
112 }
113 
OH_IPCParcel_RewindWritePosition(OHIPCParcel * parcel,uint32_t newWritePos)114 int OH_IPCParcel_RewindWritePosition(OHIPCParcel *parcel, uint32_t newWritePos)
115 {
116     return SetParcelProperty<uint32_t, size_t>(parcel, newWritePos, &OHOS::MessageParcel::RewindWrite);
117 }
118 
119 template <typename T>
WriteValue(OHIPCParcel * parcel,T value,bool (OHOS::MessageParcel::* Write)(T value))120 static int WriteValue(OHIPCParcel *parcel, T value, bool (OHOS::MessageParcel::*Write)(T value))
121 {
122     if (!IsIPCParcelValid(parcel, __func__)) {
123         return OH_IPC_CHECK_PARAM_ERROR;
124     }
125     return (parcel->msgParcel->*Write)(value) ? OH_IPC_SUCCESS : OH_IPC_PARCEL_WRITE_ERROR;
126 }
127 
128 template <typename T>
ReadValue(const OHIPCParcel * parcel,T * value,bool (OHOS::MessageParcel::* Read)(T & value))129 static int ReadValue(const OHIPCParcel *parcel, T *value, bool (OHOS::MessageParcel::*Read)(T &value))
130 {
131     if (!IsIPCParcelValid(parcel, __func__) || value == nullptr) {
132         return OH_IPC_CHECK_PARAM_ERROR;
133     }
134 
135     return (parcel->msgParcel->*Read)(*value) ? OH_IPC_SUCCESS : OH_IPC_PARCEL_READ_ERROR;
136 }
137 
OH_IPCParcel_WriteInt8(OHIPCParcel * parcel,int8_t value)138 int OH_IPCParcel_WriteInt8(OHIPCParcel *parcel, int8_t value)
139 {
140     return WriteValue<int8_t>(parcel, value, &OHOS::MessageParcel::WriteInt8);
141 }
142 
OH_IPCParcel_ReadInt8(const OHIPCParcel * parcel,int8_t * value)143 int OH_IPCParcel_ReadInt8(const OHIPCParcel *parcel, int8_t *value)
144 {
145     return ReadValue<int8_t>(parcel, value, &OHOS::MessageParcel::ReadInt8);
146 }
147 
OH_IPCParcel_WriteInt16(OHIPCParcel * parcel,int16_t value)148 int OH_IPCParcel_WriteInt16(OHIPCParcel *parcel, int16_t value)
149 {
150     return WriteValue<int16_t>(parcel, value, &OHOS::MessageParcel::WriteInt16);
151 }
152 
OH_IPCParcel_ReadInt16(const OHIPCParcel * parcel,int16_t * value)153 int OH_IPCParcel_ReadInt16(const OHIPCParcel *parcel, int16_t *value)
154 {
155     return ReadValue<int16_t>(parcel, value, &OHOS::MessageParcel::ReadInt16);
156 }
157 
OH_IPCParcel_WriteInt32(OHIPCParcel * parcel,int32_t value)158 int OH_IPCParcel_WriteInt32(OHIPCParcel *parcel, int32_t value)
159 {
160     return WriteValue<int32_t>(parcel, value, &OHOS::MessageParcel::WriteInt32);
161 }
162 
OH_IPCParcel_ReadInt32(const OHIPCParcel * parcel,int32_t * value)163 int OH_IPCParcel_ReadInt32(const OHIPCParcel *parcel, int32_t *value)
164 {
165     return ReadValue<int32_t>(parcel, value, &OHOS::MessageParcel::ReadInt32);
166 }
167 
OH_IPCParcel_WriteInt64(OHIPCParcel * parcel,int64_t value)168 int OH_IPCParcel_WriteInt64(OHIPCParcel *parcel, int64_t value)
169 {
170     return WriteValue<int64_t>(parcel, value, &OHOS::MessageParcel::WriteInt64);
171 }
172 
OH_IPCParcel_ReadInt64(const OHIPCParcel * parcel,int64_t * value)173 int OH_IPCParcel_ReadInt64(const OHIPCParcel *parcel, int64_t *value)
174 {
175     return ReadValue<int64_t>(parcel, value, &OHOS::MessageParcel::ReadInt64);
176 }
177 
OH_IPCParcel_WriteFloat(OHIPCParcel * parcel,float value)178 int OH_IPCParcel_WriteFloat(OHIPCParcel *parcel, float value)
179 {
180     return WriteValue<float>(parcel, value, &OHOS::MessageParcel::WriteFloat);
181 }
182 
OH_IPCParcel_ReadFloat(const OHIPCParcel * parcel,float * value)183 int OH_IPCParcel_ReadFloat(const OHIPCParcel *parcel, float *value)
184 {
185     return ReadValue<float>(parcel, value, &OHOS::MessageParcel::ReadFloat);
186 }
187 
OH_IPCParcel_WriteDouble(OHIPCParcel * parcel,double value)188 int OH_IPCParcel_WriteDouble(OHIPCParcel *parcel, double value)
189 {
190     return WriteValue<double>(parcel, value, &OHOS::MessageParcel::WriteDouble);
191 }
192 
OH_IPCParcel_ReadDouble(const OHIPCParcel * parcel,double * value)193 int OH_IPCParcel_ReadDouble(const OHIPCParcel *parcel, double *value)
194 {
195     return ReadValue<double>(parcel, value, &OHOS::MessageParcel::ReadDouble);
196 }
197 
OH_IPCParcel_WriteString(OHIPCParcel * parcel,const char * str)198 int OH_IPCParcel_WriteString(OHIPCParcel *parcel, const char *str)
199 {
200     if (!IsIPCParcelValid(parcel, __func__) || str == nullptr) {
201         return OH_IPC_CHECK_PARAM_ERROR;
202     }
203 
204     return parcel->msgParcel->WriteCString(str) ? OH_IPC_SUCCESS : OH_IPC_PARCEL_WRITE_ERROR;
205 }
206 
OH_IPCParcel_ReadString(const OHIPCParcel * parcel)207 const char* OH_IPCParcel_ReadString(const OHIPCParcel *parcel)
208 {
209     if (!IsIPCParcelValid(parcel, __func__)) {
210         return nullptr;
211     }
212 
213     return parcel->msgParcel->ReadCString();
214 }
215 
OH_IPCParcel_WriteBuffer(OHIPCParcel * parcel,const uint8_t * buffer,int32_t len)216 int OH_IPCParcel_WriteBuffer(OHIPCParcel *parcel, const uint8_t *buffer, int32_t len)
217 {
218     if (!IsIPCParcelValid(parcel, __func__) || buffer == nullptr || len <= 0) {
219         return OH_IPC_CHECK_PARAM_ERROR;
220     }
221 
222     size_t writePosition = parcel->msgParcel->GetWritePosition();
223     if (!parcel->msgParcel->WriteBuffer(buffer, len)) {
224         ZLOGE(LOG_LABEL, "write buffer failed! buffer len:%{public}d", len);
225         parcel->msgParcel->RewindWrite(writePosition);
226         return OH_IPC_PARCEL_WRITE_ERROR;
227     }
228     return OH_IPC_SUCCESS;
229 }
230 
OH_IPCParcel_ReadBuffer(const OHIPCParcel * parcel,int32_t len)231 const uint8_t* OH_IPCParcel_ReadBuffer(const OHIPCParcel *parcel, int32_t len)
232 {
233     if (!IsIPCParcelValid(parcel, __func__)) {
234         return nullptr;
235     }
236     int readableBytes = static_cast<int>(parcel->msgParcel->GetReadableBytes());
237     if (len <= 0 || len > readableBytes) {
238         ZLOGE(LOG_LABEL, "read buf len:%{public}d invalid! ReadableBytes:%{public}d", len, readableBytes);
239         return nullptr;
240     }
241 
242     return parcel->msgParcel->ReadBuffer(len);
243 }
244 
245 template <typename T>
WriteIPCRemoteObject(OHIPCParcel * parcel,const T * object)246 static int WriteIPCRemoteObject(OHIPCParcel *parcel, const T *object)
247 {
248     if (!IsIPCParcelValid(parcel, __func__) || object == nullptr) {
249         return OH_IPC_CHECK_PARAM_ERROR;
250     }
251     if (!parcel->msgParcel->WriteRemoteObject(object->remote)) {
252         ZLOGE(LOG_LABEL, "write remote object failed!");
253         return OH_IPC_PARCEL_WRITE_ERROR;
254     }
255     return OH_IPC_SUCCESS;
256 }
257 
258 template <typename T>
ReadIPCRemoteObject(const OHIPCParcel * parcel)259 static T* ReadIPCRemoteObject(const OHIPCParcel *parcel)
260 {
261     if (!IsIPCParcelValid(parcel, __func__)) {
262         return nullptr;
263     }
264     OHOS::sptr<OHOS::IRemoteObject> object = parcel->msgParcel->ReadRemoteObject();
265     if (object == nullptr) {
266         ZLOGE(LOG_LABEL, "read remote object failed!");
267         return nullptr;
268     }
269     T *remoteObject = new (std::nothrow) T();
270     if (remoteObject == nullptr) {
271         ZLOGE(LOG_LABEL, "new remote object failed");
272         return nullptr;
273     }
274     remoteObject->remote = object;
275     return remoteObject;
276 }
277 
OH_IPCParcel_WriteRemoteStub(OHIPCParcel * parcel,const OHIPCRemoteStub * stub)278 int OH_IPCParcel_WriteRemoteStub(OHIPCParcel *parcel, const OHIPCRemoteStub *stub)
279 {
280     return WriteIPCRemoteObject(parcel, stub);
281 }
282 
OH_IPCParcel_ReadRemoteStub(const OHIPCParcel * parcel)283 OHIPCRemoteStub* OH_IPCParcel_ReadRemoteStub(const OHIPCParcel *parcel)
284 {
285     return ReadIPCRemoteObject<OHIPCRemoteStub>(parcel);
286 }
287 
OH_IPCParcel_WriteRemoteProxy(OHIPCParcel * parcel,const OHIPCRemoteProxy * proxy)288 int OH_IPCParcel_WriteRemoteProxy(OHIPCParcel *parcel, const OHIPCRemoteProxy *proxy)
289 {
290     return WriteIPCRemoteObject(parcel, proxy);
291 }
292 
OH_IPCParcel_ReadRemoteProxy(const OHIPCParcel * parcel)293 OHIPCRemoteProxy* OH_IPCParcel_ReadRemoteProxy(const OHIPCParcel *parcel)
294 {
295     return ReadIPCRemoteObject<OHIPCRemoteProxy>(parcel);
296 }
297 
OH_IPCParcel_WriteFileDescriptor(OHIPCParcel * parcel,int32_t fd)298 int OH_IPCParcel_WriteFileDescriptor(OHIPCParcel *parcel, int32_t fd)
299 {
300     return WriteValue<int32_t>(parcel, fd, &OHOS::MessageParcel::WriteFileDescriptor);
301 }
302 
OH_IPCParcel_ReadFileDescriptor(const OHIPCParcel * parcel,int32_t * fd)303 int OH_IPCParcel_ReadFileDescriptor(const OHIPCParcel *parcel, int32_t *fd)
304 {
305     if (!IsIPCParcelValid(parcel, __func__) || fd == nullptr) {
306         return OH_IPC_CHECK_PARAM_ERROR;
307     }
308 
309     int tmpFd = parcel->msgParcel->ReadFileDescriptor();
310     if (tmpFd == -1) {
311         ZLOGE(LOG_LABEL, "read file descriptor failed!");
312         return OH_IPC_PARCEL_READ_ERROR;
313     }
314     *fd = tmpFd;
315     return OH_IPC_SUCCESS;
316 }
317 
OH_IPCParcel_Append(OHIPCParcel * parcel,const OHIPCParcel * data)318 int OH_IPCParcel_Append(OHIPCParcel *parcel, const OHIPCParcel *data)
319 {
320     if (!IsIPCParcelValid(parcel, __func__) || !IsIPCParcelValid(data, __func__)) {
321         return OH_IPC_CHECK_PARAM_ERROR;
322     }
323     return parcel->msgParcel->Append(*(data->msgParcel)) ? OH_IPC_SUCCESS : OH_IPC_PARCEL_WRITE_ERROR;
324 }
325 
OH_IPCParcel_WriteInterfaceToken(OHIPCParcel * parcel,const char * token)326 int OH_IPCParcel_WriteInterfaceToken(OHIPCParcel *parcel, const char *token)
327 {
328     if (!IsIPCParcelValid(parcel, __func__) || token == nullptr) {
329         return OH_IPC_CHECK_PARAM_ERROR;
330     }
331 
332     int tokenLen = strlen(token);
333     if (tokenLen == 0 || tokenLen > MAX_PARCEL_LEN) {
334         return OH_IPC_CHECK_PARAM_ERROR;
335     }
336     std::u16string u16Token = OHOS::Str8ToStr16(std::string(token, tokenLen));
337     if (u16Token.length() == 0 && tokenLen != 0) {
338         ZLOGE(LOG_LABEL, "convert token to u16string failed: %{public}d", tokenLen);
339         return OH_IPC_PARCEL_WRITE_ERROR;
340     }
341     size_t writePosition = parcel->msgParcel->GetWritePosition();
342     if (!parcel->msgParcel->WriteInterfaceToken(u16Token)) {
343         ZLOGE(LOG_LABEL, "WriteInterfaceToken failed! token len:%{public}d", tokenLen);
344         parcel->msgParcel->RewindWrite(writePosition);
345         return OH_IPC_PARCEL_WRITE_ERROR;
346     }
347     return OH_IPC_SUCCESS;
348 }
349 
OH_IPCParcel_ReadInterfaceToken(const OHIPCParcel * parcel,char ** token,int32_t * len,OH_IPC_MemAllocator allocator)350 int OH_IPCParcel_ReadInterfaceToken(const OHIPCParcel *parcel, char **token, int32_t *len,
351     OH_IPC_MemAllocator allocator)
352 {
353     if (!IsIPCParcelValid(parcel, __func__) || !IsMemoryParamsValid(token, len, allocator, __func__)) {
354         return OH_IPC_CHECK_PARAM_ERROR;
355     }
356     size_t readPosition = parcel->msgParcel->GetReadPosition();
357     std::u16string u16Token = parcel->msgParcel->ReadInterfaceToken();
358     std::string strToken = OHOS::Str16ToStr8(u16Token);
359     if (u16Token.length() != 0 && strToken.length() == 0) {
360         parcel->msgParcel->RewindRead(readPosition);
361         ZLOGE(LOG_LABEL, "Str16ToStr8 failed! u16Token len: %{public}u, string len: %{public}u",
362             static_cast<uint32_t>(u16Token.length()), static_cast<uint32_t>(strToken.length()));
363         return OH_IPC_PARCEL_READ_ERROR;
364     }
365 
366     int memLength = static_cast<int>(strToken.length()) + 1;
367     *token = static_cast<char *>(allocator(memLength));
368     if (*token == nullptr) {
369         parcel->msgParcel->RewindRead(readPosition);
370         ZLOGE(LOG_LABEL, "memory allocator failed!");
371         return OH_IPC_MEM_ALLOCATOR_ERROR;
372     }
373     if (memcpy_s(*token, memLength, strToken.c_str(), memLength) != EOK) {
374         parcel->msgParcel->RewindRead(readPosition);
375         ZLOGE(LOG_LABEL, "memcpy string failed, string len: %{public}d", memLength);
376         return OH_IPC_PARCEL_READ_ERROR;
377     }
378     *len = memLength;
379     return OH_IPC_SUCCESS;
380 }
381