blob: 037aa2e12085da6faaf72a7178bb08da1d7db014 [file] [log] [blame]
Steven Moreland2e87adc2018-08-20 19:47:00 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <android/binder_parcel.h>
John Reck79fb24b2020-02-14 13:56:19 -080018#include <android/binder_parcel_platform.h>
Steven Moreland4d5ad492018-09-13 12:49:16 -070019#include "parcel_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070020
Steven Moreland4d5ad492018-09-13 12:49:16 -070021#include "ibinder_internal.h"
Steven Moreland5d62e442018-09-13 15:01:02 -070022#include "status_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070023
Steven Moreland7b06f592018-10-03 19:25:32 -070024#include <limits>
25
26#include <android-base/logging.h>
Steven Moreland063f2362018-10-18 12:49:11 -070027#include <android-base/unique_fd.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070028#include <binder/Parcel.h>
Steven Moreland063f2362018-10-18 12:49:11 -070029#include <binder/ParcelFileDescriptor.h>
Steven Moreland7b06f592018-10-03 19:25:32 -070030#include <utils/Unicode.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070031
32using ::android::IBinder;
33using ::android::Parcel;
34using ::android::sp;
Steven Moreland5d62e442018-09-13 15:01:02 -070035using ::android::status_t;
Steven Moreland063f2362018-10-18 12:49:11 -070036using ::android::base::unique_fd;
37using ::android::os::ParcelFileDescriptor;
Steven Moreland2e87adc2018-08-20 19:47:00 -070038
Steven Morelanda8845662018-10-12 11:53:03 -070039template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080040using ContiguousArrayAllocator = bool (*)(void* arrayData, int32_t length, T** outBuffer);
Steven Moreland71872f82018-10-29 11:46:56 -070041
42template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080043using ArrayAllocator = bool (*)(void* arrayData, int32_t length);
Steven Morelanda8845662018-10-12 11:53:03 -070044template <typename T>
45using ArrayGetter = T (*)(const void* arrayData, size_t index);
46template <typename T>
47using ArraySetter = void (*)(void* arrayData, size_t index, T value);
48
Steven Morelandb3adc032021-05-14 20:41:11 +000049static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
50 int32_t length) {
Steven Moreland01ebcf72018-11-15 15:06:26 -080051 // only -1 can be used to represent a null array
52 if (length < -1) return STATUS_BAD_VALUE;
53
54 if (!isNullArray && length < 0) {
Steven Moreland2c20bbf2019-10-30 15:18:58 -070055 LOG(ERROR) << __func__ << ": non-null array but length is " << length;
Steven Moreland01ebcf72018-11-15 15:06:26 -080056 return STATUS_BAD_VALUE;
57 }
58 if (isNullArray && length > 0) {
59 LOG(ERROR) << __func__ << ": null buffer cannot be for size " << length << " array.";
60 return STATUS_BAD_VALUE;
61 }
Steven Morelanda8845662018-10-12 11:53:03 -070062
63 Parcel* rawParcel = parcel->get();
64
Steven Morelandb3adc032021-05-14 20:41:11 +000065 status_t status = rawParcel->writeInt32(length);
Steven Morelanda8845662018-10-12 11:53:03 -070066 if (status != STATUS_OK) return PruneStatusT(status);
67
Steven Moreland01ebcf72018-11-15 15:06:26 -080068 return STATUS_OK;
69}
70
Steven Morelandb3adc032021-05-14 20:41:11 +000071static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
72 if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
73 return PruneStatusT(status);
74 }
75
76 if (*length < -1) return STATUS_BAD_VALUE; // libbinder_ndk reserves these
77 if (*length <= 0) return STATUS_OK; // null
78 if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;
79
80 return STATUS_OK;
81}
82
Steven Moreland01ebcf72018-11-15 15:06:26 -080083template <typename T>
84binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
85 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
86 if (status != STATUS_OK) return status;
87 if (length <= 0) return STATUS_OK;
88
Steven Morelanda8845662018-10-12 11:53:03 -070089 int32_t size = 0;
90 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
91
Steven Moreland01ebcf72018-11-15 15:06:26 -080092 void* const data = parcel->get()->writeInplace(size);
Steven Morelanda8845662018-10-12 11:53:03 -070093 if (data == nullptr) return STATUS_NO_MEMORY;
94
95 memcpy(data, array, size);
96
97 return STATUS_OK;
98}
99
100// Each element in a char16_t array is converted to an int32_t (not packed).
101template <>
Steven Moreland01ebcf72018-11-15 15:06:26 -0800102binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, int32_t length) {
103 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
104 if (status != STATUS_OK) return status;
105 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700106
107 int32_t size = 0;
108 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
109
Steven Moreland01ebcf72018-11-15 15:06:26 -0800110 Parcel* rawParcel = parcel->get();
111
Steven Morelanda8845662018-10-12 11:53:03 -0700112 for (int32_t i = 0; i < length; i++) {
113 status = rawParcel->writeChar(array[i]);
114
115 if (status != STATUS_OK) return PruneStatusT(status);
116 }
117
118 return STATUS_OK;
119}
120
121template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700122binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
123 ContiguousArrayAllocator<T> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700124 const Parcel* rawParcel = parcel->get();
125
126 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000127 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
128 return status;
129 }
Steven Morelanda8845662018-10-12 11:53:03 -0700130
Steven Moreland01ebcf72018-11-15 15:06:26 -0800131 T* array;
Devin Moore7a450242022-11-15 22:21:07 +0000132 if (!allocator(arrayData, length, &array)) {
133 if (length < 0) {
134 return STATUS_UNEXPECTED_NULL;
135 } else {
136 return STATUS_NO_MEMORY;
137 }
138 }
Steven Moreland01ebcf72018-11-15 15:06:26 -0800139
140 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700141 if (array == nullptr) return STATUS_NO_MEMORY;
142
143 int32_t size = 0;
144 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
145
146 const void* data = rawParcel->readInplace(size);
147 if (data == nullptr) return STATUS_NO_MEMORY;
148
149 memcpy(array, data, size);
150
151 return STATUS_OK;
152}
153
154// Each element in a char16_t array is converted to an int32_t (not packed)
155template <>
Steven Moreland71872f82018-10-29 11:46:56 -0700156binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
157 ContiguousArrayAllocator<char16_t> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700158 const Parcel* rawParcel = parcel->get();
159
160 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000161 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
162 return status;
163 }
Steven Morelanda8845662018-10-12 11:53:03 -0700164
Steven Moreland01ebcf72018-11-15 15:06:26 -0800165 char16_t* array;
Devin Moore7a450242022-11-15 22:21:07 +0000166 if (!allocator(arrayData, length, &array)) {
167 if (length < 0) {
168 return STATUS_UNEXPECTED_NULL;
169 } else {
170 return STATUS_NO_MEMORY;
171 }
172 }
Steven Moreland01ebcf72018-11-15 15:06:26 -0800173
174 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700175 if (array == nullptr) return STATUS_NO_MEMORY;
176
177 int32_t size = 0;
178 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
179
180 for (int32_t i = 0; i < length; i++) {
Steven Morelandb3adc032021-05-14 20:41:11 +0000181 status_t status = rawParcel->readChar(array + i);
Steven Morelanda8845662018-10-12 11:53:03 -0700182
183 if (status != STATUS_OK) return PruneStatusT(status);
184 }
185
186 return STATUS_OK;
187}
188
189template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -0800190binder_status_t WriteArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland16e1eae2018-11-01 09:51:53 -0700191 ArrayGetter<T> getter, status_t (Parcel::*write)(T)) {
Steven Moreland01ebcf72018-11-15 15:06:26 -0800192 // we have no clue if arrayData represents a null object or not, we can only infer from length
193 bool arrayIsNull = length < 0;
194 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
195 if (status != STATUS_OK) return status;
196 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700197
198 Parcel* rawParcel = parcel->get();
199
Steven Moreland763dc4c2018-12-12 11:30:06 -0800200 for (int32_t i = 0; i < length; i++) {
Steven Morelanda8845662018-10-12 11:53:03 -0700201 status = (rawParcel->*write)(getter(arrayData, i));
202
203 if (status != STATUS_OK) return PruneStatusT(status);
204 }
205
206 return STATUS_OK;
207}
208
209template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700210binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator<T> allocator,
211 ArraySetter<T> setter, status_t (Parcel::*read)(T*) const) {
Steven Morelanda8845662018-10-12 11:53:03 -0700212 const Parcel* rawParcel = parcel->get();
213
214 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000215 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
216 return status;
217 }
Steven Morelanda8845662018-10-12 11:53:03 -0700218
Devin Moore7a450242022-11-15 22:21:07 +0000219 if (!allocator(arrayData, length)) {
220 if (length < 0) {
221 return STATUS_UNEXPECTED_NULL;
222 } else {
223 return STATUS_NO_MEMORY;
224 }
225 }
Steven Morelanda8845662018-10-12 11:53:03 -0700226
Steven Moreland01ebcf72018-11-15 15:06:26 -0800227 if (length <= 0) return STATUS_OK;
228
Steven Moreland763dc4c2018-12-12 11:30:06 -0800229 for (int32_t i = 0; i < length; i++) {
Steven Morelanda8845662018-10-12 11:53:03 -0700230 T readTarget;
Steven Morelandb3adc032021-05-14 20:41:11 +0000231 status_t status = (rawParcel->*read)(&readTarget);
Steven Morelanda8845662018-10-12 11:53:03 -0700232 if (status != STATUS_OK) return PruneStatusT(status);
233
Steven Moreland71872f82018-10-29 11:46:56 -0700234 setter(arrayData, i, readTarget);
Steven Morelanda8845662018-10-12 11:53:03 -0700235 }
236
237 return STATUS_OK;
238}
239
Steven Moreland9b80e282018-09-19 13:57:23 -0700240void AParcel_delete(AParcel* parcel) {
241 delete parcel;
Steven Morelandcaa776c2018-09-04 13:48:11 -0700242}
243
Steven Morelandf32d1b02018-11-27 12:44:10 -0800244binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
245 if (position < 0) {
246 return STATUS_BAD_VALUE;
247 }
248
249 parcel->get()->setDataPosition(position);
250 return STATUS_OK;
251}
252
253int32_t AParcel_getDataPosition(const AParcel* parcel) {
254 return parcel->get()->dataPosition();
255}
256
Steven Morelandf183fdd2020-10-27 00:12:12 +0000257void AParcel_markSensitive(const AParcel* parcel) {
258 return parcel->get()->markSensitive();
259}
260
Steven Moreland2e87adc2018-08-20 19:47:00 -0700261binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
Steven Morelandc0e46d32018-09-12 15:40:49 -0700262 sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700263 return parcel->get()->writeStrongBinder(writeBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700264}
265binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
266 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700267 status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700268 if (status != STATUS_OK) {
269 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700270 }
Steven Moreland94968952018-09-05 14:42:59 -0700271 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700272 AIBinder_incStrong(ret.get());
Steven Moreland418914a2023-06-28 21:47:14 +0000273
274 if (ret.get() != nullptr && parcel->get()->isServiceFuzzing()) {
275 if (auto bp = ret->asABpBinder(); bp != nullptr) {
276 bp->setServiceFuzzing();
277 }
278 }
279
Steven Moreland71cddc32018-08-30 23:39:22 -0700280 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700281 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700282}
Steven Moreland063f2362018-10-18 12:49:11 -0700283
284binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
Steven Moreland4ce59c72018-11-16 15:21:15 -0800285 if (fd < 0) {
286 if (fd != -1) {
287 return STATUS_UNKNOWN_ERROR;
288 }
Steven Moreland073c9c12020-02-19 17:02:08 -0800289 return PruneStatusT(parcel->get()->writeInt32(0)); // null
Steven Moreland4ce59c72018-11-16 15:21:15 -0800290 }
Steven Moreland073c9c12020-02-19 17:02:08 -0800291 status_t status = parcel->get()->writeInt32(1); // not-null
292 if (status != STATUS_OK) return PruneStatusT(status);
Steven Moreland4ce59c72018-11-16 15:21:15 -0800293
Steven Moreland073c9c12020-02-19 17:02:08 -0800294 status = parcel->get()->writeDupParcelFileDescriptor(fd);
Steven Moreland063f2362018-10-18 12:49:11 -0700295 return PruneStatusT(status);
296}
297
298binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
Jooyung Han4d9f91a2020-11-18 13:24:16 +0900299 std::optional<ParcelFileDescriptor> parcelFd;
Steven Moreland4ce59c72018-11-16 15:21:15 -0800300
Steven Moreland063f2362018-10-18 12:49:11 -0700301 status_t status = parcel->get()->readParcelable(&parcelFd);
302 if (status != STATUS_OK) return PruneStatusT(status);
303
Steven Moreland4ce59c72018-11-16 15:21:15 -0800304 if (parcelFd) {
305 *fd = parcelFd->release().release();
306 } else {
307 *fd = -1;
308 }
309
Steven Moreland063f2362018-10-18 12:49:11 -0700310 return STATUS_OK;
311}
312
Steven Moreland9a51db82018-09-14 10:59:35 -0700313binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
Steven Moreland85c138a2020-09-22 22:00:52 +0000314 return PruneStatusT(status->get().writeToParcel(parcel->get()));
Steven Moreland9a51db82018-09-14 10:59:35 -0700315}
316binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
317 ::android::binder::Status bstatus;
318 binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
Steven Morelandc1a11b82018-10-29 18:47:23 -0700319 if (ret == STATUS_OK) {
Steven Moreland9a51db82018-09-14 10:59:35 -0700320 *status = new AStatus(std::move(bstatus));
321 }
Steven Morelandc1a11b82018-10-29 18:47:23 -0700322 return PruneStatusT(ret);
Steven Moreland9a51db82018-09-14 10:59:35 -0700323}
Steven Moreland2e87adc2018-08-20 19:47:00 -0700324
Steven Morelandb4e14612018-11-14 17:25:45 -0800325binder_status_t AParcel_writeString(AParcel* parcel, const char* string, int32_t length) {
326 if (string == nullptr) {
327 if (length != -1) {
328 LOG(WARNING) << __func__ << ": null string must be used with length == -1.";
329 return STATUS_BAD_VALUE;
330 }
Steven Moreland7b06f592018-10-03 19:25:32 -0700331
Steven Morelandb4e14612018-11-14 17:25:45 -0800332 status_t err = parcel->get()->writeInt32(-1);
333 return PruneStatusT(err);
334 }
335
336 if (length < 0) {
337 LOG(WARNING) << __func__ << ": Negative string length: " << length;
338 return STATUS_BAD_VALUE;
339 }
340
341 const uint8_t* str8 = (uint8_t*)string;
Steven Moreland7b06f592018-10-03 19:25:32 -0700342 const ssize_t len16 = utf8_to_utf16_length(str8, length);
343
344 if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
345 LOG(WARNING) << __func__ << ": Invalid string length: " << len16;
346 return STATUS_BAD_VALUE;
347 }
348
349 status_t err = parcel->get()->writeInt32(len16);
350 if (err) {
351 return PruneStatusT(err);
352 }
353
354 void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
355 if (str16 == nullptr) {
356 return STATUS_NO_MEMORY;
357 }
358
359 utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
360
361 return STATUS_OK;
362}
363
Steven Moreland07fb9c92018-11-01 17:14:29 -0700364binder_status_t AParcel_readString(const AParcel* parcel, void* stringData,
365 AParcel_stringAllocator allocator) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700366 size_t len16;
367 const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
368
369 if (str16 == nullptr) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800370 if (allocator(stringData, -1, nullptr)) {
371 return STATUS_OK;
372 }
373
Steven Moreland7b06f592018-10-03 19:25:32 -0700374 return STATUS_UNEXPECTED_NULL;
375 }
376
377 ssize_t len8;
378
379 if (len16 == 0) {
380 len8 = 1;
381 } else {
382 len8 = utf16_to_utf8_length(str16, len16) + 1;
383 }
384
Steven Moreland07fb9c92018-11-01 17:14:29 -0700385 if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700386 LOG(WARNING) << __func__ << ": Invalid string length: " << len8;
387 return STATUS_BAD_VALUE;
388 }
389
Steven Morelandb4e14612018-11-14 17:25:45 -0800390 char* str8;
391 bool success = allocator(stringData, len8, &str8);
Steven Moreland7b06f592018-10-03 19:25:32 -0700392
Steven Morelandb4e14612018-11-14 17:25:45 -0800393 if (!success || str8 == nullptr) {
Steven Moreland71872f82018-10-29 11:46:56 -0700394 LOG(WARNING) << __func__ << ": AParcel_stringAllocator failed to allocate.";
Steven Moreland7b06f592018-10-03 19:25:32 -0700395 return STATUS_NO_MEMORY;
396 }
397
398 utf16_to_utf8(str16, len16, str8, len8);
399
400 return STATUS_OK;
401}
402
Steven Morelandb4e14612018-11-14 17:25:45 -0800403binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland07fb9c92018-11-01 17:14:29 -0700404 AParcel_stringArrayElementGetter getter) {
Steven Moreland01ebcf72018-11-15 15:06:26 -0800405 // we have no clue if arrayData represents a null object or not, we can only infer from length
406 bool arrayIsNull = length < 0;
407 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
408 if (status != STATUS_OK) return status;
409 if (length <= 0) return STATUS_OK;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700410
Steven Moreland763dc4c2018-12-12 11:30:06 -0800411 for (int32_t i = 0; i < length; i++) {
412 int32_t elementLength = 0;
Steven Morelande22a9942018-12-11 18:57:05 -0800413 const char* str = getter(arrayData, i, &elementLength);
414 if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700415
Steven Morelande22a9942018-12-11 18:57:05 -0800416 binder_status_t status = AParcel_writeString(parcel, str, elementLength);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700417 if (status != STATUS_OK) return status;
418 }
419
420 return STATUS_OK;
421}
422
423// This implements AParcel_stringAllocator for a string using an array, index, and element
424// allocator.
425struct StringArrayElementAllocationAdapter {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700426 void* arrayData; // stringData from the NDK
Steven Moreland763dc4c2018-12-12 11:30:06 -0800427 int32_t index; // index into the string array
Steven Moreland07fb9c92018-11-01 17:14:29 -0700428 AParcel_stringArrayElementAllocator elementAllocator;
429
Steven Morelandb4e14612018-11-14 17:25:45 -0800430 static bool Allocator(void* stringData, int32_t length, char** buffer) {
Steven Moreland07fb9c92018-11-01 17:14:29 -0700431 StringArrayElementAllocationAdapter* adapter =
432 static_cast<StringArrayElementAllocationAdapter*>(stringData);
Steven Morelandb4e14612018-11-14 17:25:45 -0800433 return adapter->elementAllocator(adapter->arrayData, adapter->index, length, buffer);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700434 }
435};
436
437binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
438 AParcel_stringArrayAllocator allocator,
439 AParcel_stringArrayElementAllocator elementAllocator) {
Steven Moreland07fb9c92018-11-01 17:14:29 -0700440 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000441 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
442 return status;
443 }
Steven Moreland07fb9c92018-11-01 17:14:29 -0700444
445 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
446
Steven Morelandb4e14612018-11-14 17:25:45 -0800447 if (length == -1) return STATUS_OK; // null string array
448
Steven Moreland07fb9c92018-11-01 17:14:29 -0700449 StringArrayElementAllocationAdapter adapter{
450 .arrayData = arrayData,
451 .index = 0,
452 .elementAllocator = elementAllocator,
453 };
454
455 for (; adapter.index < length; adapter.index++) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800456 binder_status_t status = AParcel_readString(parcel, static_cast<void*>(&adapter),
457 StringArrayElementAllocationAdapter::Allocator);
458
459 if (status != STATUS_OK) return status;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700460 }
461
462 return STATUS_OK;
463}
464
Steven Morelande22a9942018-12-11 18:57:05 -0800465binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
466 AParcel_writeParcelableElement elementWriter) {
467 // we have no clue if arrayData represents a null object or not, we can only infer from length
468 bool arrayIsNull = length < 0;
469 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
470 if (status != STATUS_OK) return status;
471 if (length <= 0) return STATUS_OK;
472
Steven Moreland763dc4c2018-12-12 11:30:06 -0800473 for (int32_t i = 0; i < length; i++) {
Steven Morelande22a9942018-12-11 18:57:05 -0800474 binder_status_t status = elementWriter(parcel, arrayData, i);
475 if (status != STATUS_OK) return status;
476 }
477
478 return STATUS_OK;
479}
480
481binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
482 AParcel_parcelableArrayAllocator allocator,
483 AParcel_readParcelableElement elementReader) {
Steven Morelande22a9942018-12-11 18:57:05 -0800484 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000485 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
486 return status;
487 }
Steven Morelande22a9942018-12-11 18:57:05 -0800488
489 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
490
491 if (length == -1) return STATUS_OK; // null array
492
Steven Moreland763dc4c2018-12-12 11:30:06 -0800493 for (int32_t i = 0; i < length; i++) {
Steven Morelande22a9942018-12-11 18:57:05 -0800494 binder_status_t status = elementReader(parcel, arrayData, i);
495 if (status != STATUS_OK) return status;
496 }
497
498 return STATUS_OK;
499}
500
Steven Moreland2e87adc2018-08-20 19:47:00 -0700501// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
502// libbinder and this library.
503// @START
504binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700505 status_t status = parcel->get()->writeInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700506 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700507}
508
509binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700510 status_t status = parcel->get()->writeUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700511 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700512}
513
514binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700515 status_t status = parcel->get()->writeInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700516 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700517}
518
519binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700520 status_t status = parcel->get()->writeUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700521 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700522}
523
524binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700525 status_t status = parcel->get()->writeFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700526 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700527}
528
529binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700530 status_t status = parcel->get()->writeDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700531 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700532}
533
534binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700535 status_t status = parcel->get()->writeBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700536 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700537}
538
539binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700540 status_t status = parcel->get()->writeChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700541 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700542}
543
544binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700545 status_t status = parcel->get()->writeByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700546 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700547}
548
549binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700550 status_t status = parcel->get()->readInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700551 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700552}
553
554binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700555 status_t status = parcel->get()->readUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700556 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700557}
558
559binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700560 status_t status = parcel->get()->readInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700561 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700562}
563
564binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700565 status_t status = parcel->get()->readUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700566 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700567}
568
569binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700570 status_t status = parcel->get()->readFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700571 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700572}
573
574binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700575 status_t status = parcel->get()->readDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700576 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700577}
578
579binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700580 status_t status = parcel->get()->readBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700581 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700582}
583
584binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700585 status_t status = parcel->get()->readChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700586 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700587}
588
589binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700590 status_t status = parcel->get()->readByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700591 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700592}
593
Steven Moreland01ebcf72018-11-15 15:06:26 -0800594binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700595 return WriteArray<int32_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700596}
597
Steven Morelande3d09582018-11-02 19:29:36 -0700598binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* arrayData,
Steven Moreland01ebcf72018-11-15 15:06:26 -0800599 int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700600 return WriteArray<uint32_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700601}
602
Steven Moreland01ebcf72018-11-15 15:06:26 -0800603binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700604 return WriteArray<int64_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700605}
606
Steven Morelande3d09582018-11-02 19:29:36 -0700607binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* arrayData,
Steven Moreland01ebcf72018-11-15 15:06:26 -0800608 int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700609 return WriteArray<uint64_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700610}
611
Steven Moreland01ebcf72018-11-15 15:06:26 -0800612binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700613 return WriteArray<float>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700614}
615
Steven Moreland01ebcf72018-11-15 15:06:26 -0800616binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700617 return WriteArray<double>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700618}
619
Steven Moreland01ebcf72018-11-15 15:06:26 -0800620binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland16e1eae2018-11-01 09:51:53 -0700621 AParcel_boolArrayGetter getter) {
622 return WriteArray<bool>(parcel, arrayData, length, getter, &Parcel::writeBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700623}
624
Steven Moreland01ebcf72018-11-15 15:06:26 -0800625binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700626 return WriteArray<char16_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700627}
628
Steven Moreland01ebcf72018-11-15 15:06:26 -0800629binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700630 return WriteArray<int8_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700631}
632
Steven Moreland71872f82018-10-29 11:46:56 -0700633binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700634 AParcel_int32ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700635 return ReadArray<int32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700636}
637
Steven Moreland71872f82018-10-29 11:46:56 -0700638binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700639 AParcel_uint32ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700640 return ReadArray<uint32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700641}
642
Steven Moreland71872f82018-10-29 11:46:56 -0700643binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700644 AParcel_int64ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700645 return ReadArray<int64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700646}
647
Steven Moreland71872f82018-10-29 11:46:56 -0700648binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700649 AParcel_uint64ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700650 return ReadArray<uint64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700651}
652
Steven Moreland71872f82018-10-29 11:46:56 -0700653binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700654 AParcel_floatArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700655 return ReadArray<float>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700656}
657
Steven Moreland71872f82018-10-29 11:46:56 -0700658binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700659 AParcel_doubleArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700660 return ReadArray<double>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700661}
662
Steven Moreland71872f82018-10-29 11:46:56 -0700663binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700664 AParcel_boolArrayAllocator allocator,
Steven Morelanda8845662018-10-12 11:53:03 -0700665 AParcel_boolArraySetter setter) {
Steven Moreland71872f82018-10-29 11:46:56 -0700666 return ReadArray<bool>(parcel, arrayData, allocator, setter, &Parcel::readBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700667}
668
Steven Moreland71872f82018-10-29 11:46:56 -0700669binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700670 AParcel_charArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700671 return ReadArray<char16_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700672}
673
Steven Moreland71872f82018-10-29 11:46:56 -0700674binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700675 AParcel_byteArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700676 return ReadArray<int8_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700677}
678
John Reck79fb24b2020-02-14 13:56:19 -0800679bool AParcel_getAllowFds(const AParcel* parcel) {
680 return parcel->get()->allowFds();
681}
682
Jeongik Cha62240b92020-10-14 00:06:01 +0900683binder_status_t AParcel_reset(AParcel* parcel) {
684 parcel->get()->freeData();
685 return STATUS_OK;
686}
687
688int32_t AParcel_getDataSize(const AParcel* parcel) {
689 return parcel->get()->dataSize();
690}
691
692binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) {
693 status_t status = to->get()->appendFrom(from->get(), start, size);
694 return PruneStatusT(status);
695}
696
697AParcel* AParcel_create() {
698 return new AParcel(nullptr);
699}
700
Yu Shanfb39f9c2021-08-25 14:58:09 -0700701binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len) {
702 if (parcel->get()->objectsCount()) {
703 return STATUS_INVALID_OPERATION;
704 }
Pawan Waghd886a442023-01-21 02:16:38 +0000705 // b/264739302 - getDataSize will return dataPos if it is greater than dataSize
706 // which will cause crashes in memcpy at later point. Instead compare with
707 // actual length of internal buffer
708 int32_t dataSize = parcel->get()->dataBufferSize();
Yu Shanfb39f9c2021-08-25 14:58:09 -0700709 if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
710 return STATUS_BAD_VALUE;
711 }
712 const uint8_t* internalBuffer = parcel->get()->data();
Pawan Wagh0beb9562023-01-20 19:11:39 +0000713 if (internalBuffer == nullptr) {
714 return STATUS_UNEXPECTED_NULL;
715 }
Yu Shanfb39f9c2021-08-25 14:58:09 -0700716 memcpy(buffer, internalBuffer + start, len);
717 return STATUS_OK;
718}
719
720binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len) {
721 status_t status = parcel->get()->setDataSize(len);
722 if (status != ::android::OK) {
723 return PruneStatusT(status);
724 }
725 parcel->get()->setDataPosition(0);
726
727 void* raw = parcel->get()->writeInplace(len);
728 if (raw == nullptr) {
729 return STATUS_NO_MEMORY;
730 }
731 memcpy(raw, buffer, len);
732 return STATUS_OK;
733}
734
Steven Moreland2e87adc2018-08-20 19:47:00 -0700735// @END