blob: 88ce5f4d9b6f37dc4583a03000e09ae97e4adaa8 [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>
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -070019#include <binder/Parcel.h>
20#include <binder/ParcelFileDescriptor.h>
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -070021#include <binder/unique_fd.h>
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -070022#include <inttypes.h>
23#include <utils/Unicode.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070024
Steven Moreland7b06f592018-10-03 19:25:32 -070025#include <limits>
26
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -070027#include "ibinder_internal.h"
28#include "parcel_internal.h"
29#include "status_internal.h"
Steven Moreland2e87adc2018-08-20 19:47:00 -070030
31using ::android::IBinder;
32using ::android::Parcel;
33using ::android::sp;
Steven Moreland5d62e442018-09-13 15:01:02 -070034using ::android::status_t;
Tomasz Wasilczyk639490b2023-11-01 13:49:41 -070035using ::android::binder::unique_fd;
Steven Moreland063f2362018-10-18 12:49:11 -070036using ::android::os::ParcelFileDescriptor;
Steven Moreland2e87adc2018-08-20 19:47:00 -070037
Steven Morelanda8845662018-10-12 11:53:03 -070038template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080039using ContiguousArrayAllocator = bool (*)(void* arrayData, int32_t length, T** outBuffer);
Steven Moreland71872f82018-10-29 11:46:56 -070040
41template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -080042using ArrayAllocator = bool (*)(void* arrayData, int32_t length);
Steven Morelanda8845662018-10-12 11:53:03 -070043template <typename T>
44using ArrayGetter = T (*)(const void* arrayData, size_t index);
45template <typename T>
46using ArraySetter = void (*)(void* arrayData, size_t index, T value);
47
Steven Morelandb3adc032021-05-14 20:41:11 +000048static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
49 int32_t length) {
Steven Moreland01ebcf72018-11-15 15:06:26 -080050 // only -1 can be used to represent a null array
51 if (length < -1) return STATUS_BAD_VALUE;
52
53 if (!isNullArray && length < 0) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -070054 ALOGE("non-null array but length is %" PRIi32, length);
Steven Moreland01ebcf72018-11-15 15:06:26 -080055 return STATUS_BAD_VALUE;
56 }
57 if (isNullArray && length > 0) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -070058 ALOGE("null buffer cannot be for size %" PRIi32 " array.", length);
Steven Moreland01ebcf72018-11-15 15:06:26 -080059 return STATUS_BAD_VALUE;
60 }
Steven Morelanda8845662018-10-12 11:53:03 -070061
62 Parcel* rawParcel = parcel->get();
63
Steven Morelandb3adc032021-05-14 20:41:11 +000064 status_t status = rawParcel->writeInt32(length);
Steven Morelanda8845662018-10-12 11:53:03 -070065 if (status != STATUS_OK) return PruneStatusT(status);
66
Steven Moreland01ebcf72018-11-15 15:06:26 -080067 return STATUS_OK;
68}
69
Steven Morelandb3adc032021-05-14 20:41:11 +000070static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
71 if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
72 return PruneStatusT(status);
73 }
74
75 if (*length < -1) return STATUS_BAD_VALUE; // libbinder_ndk reserves these
76 if (*length <= 0) return STATUS_OK; // null
77 if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;
78
79 return STATUS_OK;
80}
81
Steven Moreland01ebcf72018-11-15 15:06:26 -080082template <typename T>
83binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
84 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
85 if (status != STATUS_OK) return status;
86 if (length <= 0) return STATUS_OK;
87
Steven Morelanda8845662018-10-12 11:53:03 -070088 int32_t size = 0;
89 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
90
Steven Moreland01ebcf72018-11-15 15:06:26 -080091 void* const data = parcel->get()->writeInplace(size);
Steven Morelanda8845662018-10-12 11:53:03 -070092 if (data == nullptr) return STATUS_NO_MEMORY;
93
94 memcpy(data, array, size);
95
96 return STATUS_OK;
97}
98
99// Each element in a char16_t array is converted to an int32_t (not packed).
100template <>
Steven Moreland01ebcf72018-11-15 15:06:26 -0800101binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, int32_t length) {
102 binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
103 if (status != STATUS_OK) return status;
104 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700105
106 int32_t size = 0;
107 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
108
Steven Moreland01ebcf72018-11-15 15:06:26 -0800109 Parcel* rawParcel = parcel->get();
110
Steven Morelanda8845662018-10-12 11:53:03 -0700111 for (int32_t i = 0; i < length; i++) {
112 status = rawParcel->writeChar(array[i]);
113
114 if (status != STATUS_OK) return PruneStatusT(status);
115 }
116
117 return STATUS_OK;
118}
119
120template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700121binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
122 ContiguousArrayAllocator<T> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700123 const Parcel* rawParcel = parcel->get();
124
125 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000126 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
127 return status;
128 }
Steven Morelanda8845662018-10-12 11:53:03 -0700129
Steven Moreland01ebcf72018-11-15 15:06:26 -0800130 T* array;
Devin Moore7a450242022-11-15 22:21:07 +0000131 if (!allocator(arrayData, length, &array)) {
132 if (length < 0) {
133 return STATUS_UNEXPECTED_NULL;
134 } else {
135 return STATUS_NO_MEMORY;
136 }
137 }
Steven Moreland01ebcf72018-11-15 15:06:26 -0800138
139 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700140 if (array == nullptr) return STATUS_NO_MEMORY;
141
142 int32_t size = 0;
143 if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
144
145 const void* data = rawParcel->readInplace(size);
146 if (data == nullptr) return STATUS_NO_MEMORY;
147
148 memcpy(array, data, size);
149
150 return STATUS_OK;
151}
152
153// Each element in a char16_t array is converted to an int32_t (not packed)
154template <>
Steven Moreland71872f82018-10-29 11:46:56 -0700155binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
156 ContiguousArrayAllocator<char16_t> allocator) {
Steven Morelanda8845662018-10-12 11:53:03 -0700157 const Parcel* rawParcel = parcel->get();
158
159 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000160 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
161 return status;
162 }
Steven Morelanda8845662018-10-12 11:53:03 -0700163
Steven Moreland01ebcf72018-11-15 15:06:26 -0800164 char16_t* array;
Devin Moore7a450242022-11-15 22:21:07 +0000165 if (!allocator(arrayData, length, &array)) {
166 if (length < 0) {
167 return STATUS_UNEXPECTED_NULL;
168 } else {
169 return STATUS_NO_MEMORY;
170 }
171 }
Steven Moreland01ebcf72018-11-15 15:06:26 -0800172
173 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700174 if (array == nullptr) return STATUS_NO_MEMORY;
175
176 int32_t size = 0;
177 if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
178
179 for (int32_t i = 0; i < length; i++) {
Steven Morelandb3adc032021-05-14 20:41:11 +0000180 status_t status = rawParcel->readChar(array + i);
Steven Morelanda8845662018-10-12 11:53:03 -0700181
182 if (status != STATUS_OK) return PruneStatusT(status);
183 }
184
185 return STATUS_OK;
186}
187
188template <typename T>
Steven Moreland01ebcf72018-11-15 15:06:26 -0800189binder_status_t WriteArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland16e1eae2018-11-01 09:51:53 -0700190 ArrayGetter<T> getter, status_t (Parcel::*write)(T)) {
Steven Moreland01ebcf72018-11-15 15:06:26 -0800191 // we have no clue if arrayData represents a null object or not, we can only infer from length
192 bool arrayIsNull = length < 0;
193 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
194 if (status != STATUS_OK) return status;
195 if (length <= 0) return STATUS_OK;
Steven Morelanda8845662018-10-12 11:53:03 -0700196
197 Parcel* rawParcel = parcel->get();
198
Steven Moreland763dc4c2018-12-12 11:30:06 -0800199 for (int32_t i = 0; i < length; i++) {
Steven Morelanda8845662018-10-12 11:53:03 -0700200 status = (rawParcel->*write)(getter(arrayData, i));
201
202 if (status != STATUS_OK) return PruneStatusT(status);
203 }
204
205 return STATUS_OK;
206}
207
208template <typename T>
Steven Moreland71872f82018-10-29 11:46:56 -0700209binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator<T> allocator,
210 ArraySetter<T> setter, status_t (Parcel::*read)(T*) const) {
Steven Morelanda8845662018-10-12 11:53:03 -0700211 const Parcel* rawParcel = parcel->get();
212
213 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000214 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
215 return status;
216 }
Steven Morelanda8845662018-10-12 11:53:03 -0700217
Devin Moore7a450242022-11-15 22:21:07 +0000218 if (!allocator(arrayData, length)) {
219 if (length < 0) {
220 return STATUS_UNEXPECTED_NULL;
221 } else {
222 return STATUS_NO_MEMORY;
223 }
224 }
Steven Morelanda8845662018-10-12 11:53:03 -0700225
Steven Moreland01ebcf72018-11-15 15:06:26 -0800226 if (length <= 0) return STATUS_OK;
227
Steven Moreland763dc4c2018-12-12 11:30:06 -0800228 for (int32_t i = 0; i < length; i++) {
Steven Morelanda8845662018-10-12 11:53:03 -0700229 T readTarget;
Steven Morelandb3adc032021-05-14 20:41:11 +0000230 status_t status = (rawParcel->*read)(&readTarget);
Steven Morelanda8845662018-10-12 11:53:03 -0700231 if (status != STATUS_OK) return PruneStatusT(status);
232
Steven Moreland71872f82018-10-29 11:46:56 -0700233 setter(arrayData, i, readTarget);
Steven Morelanda8845662018-10-12 11:53:03 -0700234 }
235
236 return STATUS_OK;
237}
238
Steven Moreland9b80e282018-09-19 13:57:23 -0700239void AParcel_delete(AParcel* parcel) {
240 delete parcel;
Steven Morelandcaa776c2018-09-04 13:48:11 -0700241}
242
Steven Morelandf32d1b02018-11-27 12:44:10 -0800243binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
244 if (position < 0) {
245 return STATUS_BAD_VALUE;
246 }
247
248 parcel->get()->setDataPosition(position);
249 return STATUS_OK;
250}
251
252int32_t AParcel_getDataPosition(const AParcel* parcel) {
253 return parcel->get()->dataPosition();
254}
255
Steven Morelandf183fdd2020-10-27 00:12:12 +0000256void AParcel_markSensitive(const AParcel* parcel) {
257 return parcel->get()->markSensitive();
258}
259
Steven Moreland2e87adc2018-08-20 19:47:00 -0700260binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
Steven Morelandc0e46d32018-09-12 15:40:49 -0700261 sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700262 return parcel->get()->writeStrongBinder(writeBinder);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700263}
264binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
265 sp<IBinder> readBinder = nullptr;
Steven Morelandf18615b2018-09-14 11:43:06 -0700266 status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
Steven Moreland5d62e442018-09-13 15:01:02 -0700267 if (status != STATUS_OK) {
268 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700269 }
Steven Moreland94968952018-09-05 14:42:59 -0700270 sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
Steven Moreland71cddc32018-08-30 23:39:22 -0700271 AIBinder_incStrong(ret.get());
Steven Moreland418914a2023-06-28 21:47:14 +0000272
273 if (ret.get() != nullptr && parcel->get()->isServiceFuzzing()) {
274 if (auto bp = ret->asABpBinder(); bp != nullptr) {
275 bp->setServiceFuzzing();
276 }
277 }
278
Steven Moreland71cddc32018-08-30 23:39:22 -0700279 *binder = ret.get();
Steven Moreland5d62e442018-09-13 15:01:02 -0700280 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700281}
Steven Moreland063f2362018-10-18 12:49:11 -0700282
283binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
Steven Moreland4ce59c72018-11-16 15:21:15 -0800284 if (fd < 0) {
285 if (fd != -1) {
286 return STATUS_UNKNOWN_ERROR;
287 }
Steven Moreland073c9c12020-02-19 17:02:08 -0800288 return PruneStatusT(parcel->get()->writeInt32(0)); // null
Steven Moreland4ce59c72018-11-16 15:21:15 -0800289 }
Steven Moreland073c9c12020-02-19 17:02:08 -0800290 status_t status = parcel->get()->writeInt32(1); // not-null
291 if (status != STATUS_OK) return PruneStatusT(status);
Steven Moreland4ce59c72018-11-16 15:21:15 -0800292
Steven Moreland073c9c12020-02-19 17:02:08 -0800293 status = parcel->get()->writeDupParcelFileDescriptor(fd);
Steven Moreland063f2362018-10-18 12:49:11 -0700294 return PruneStatusT(status);
295}
296
297binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
Jooyung Han4d9f91a2020-11-18 13:24:16 +0900298 std::optional<ParcelFileDescriptor> parcelFd;
Steven Moreland4ce59c72018-11-16 15:21:15 -0800299
Steven Moreland063f2362018-10-18 12:49:11 -0700300 status_t status = parcel->get()->readParcelable(&parcelFd);
301 if (status != STATUS_OK) return PruneStatusT(status);
302
Steven Moreland4ce59c72018-11-16 15:21:15 -0800303 if (parcelFd) {
304 *fd = parcelFd->release().release();
305 } else {
306 *fd = -1;
307 }
308
Steven Moreland063f2362018-10-18 12:49:11 -0700309 return STATUS_OK;
310}
311
Steven Moreland9a51db82018-09-14 10:59:35 -0700312binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
Steven Moreland85c138a2020-09-22 22:00:52 +0000313 return PruneStatusT(status->get().writeToParcel(parcel->get()));
Steven Moreland9a51db82018-09-14 10:59:35 -0700314}
315binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
316 ::android::binder::Status bstatus;
317 binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
Steven Morelandc1a11b82018-10-29 18:47:23 -0700318 if (ret == STATUS_OK) {
Steven Moreland9a51db82018-09-14 10:59:35 -0700319 *status = new AStatus(std::move(bstatus));
320 }
Steven Morelandc1a11b82018-10-29 18:47:23 -0700321 return PruneStatusT(ret);
Steven Moreland9a51db82018-09-14 10:59:35 -0700322}
Steven Moreland2e87adc2018-08-20 19:47:00 -0700323
Steven Morelandb4e14612018-11-14 17:25:45 -0800324binder_status_t AParcel_writeString(AParcel* parcel, const char* string, int32_t length) {
325 if (string == nullptr) {
326 if (length != -1) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700327 ALOGW("null string must be used with length == -1.");
Steven Morelandb4e14612018-11-14 17:25:45 -0800328 return STATUS_BAD_VALUE;
329 }
Steven Moreland7b06f592018-10-03 19:25:32 -0700330
Steven Morelandb4e14612018-11-14 17:25:45 -0800331 status_t err = parcel->get()->writeInt32(-1);
332 return PruneStatusT(err);
333 }
334
335 if (length < 0) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700336 ALOGW("Negative string length: %" PRIi32, length);
Steven Morelandb4e14612018-11-14 17:25:45 -0800337 return STATUS_BAD_VALUE;
338 }
339
340 const uint8_t* str8 = (uint8_t*)string;
Steven Moreland7b06f592018-10-03 19:25:32 -0700341 const ssize_t len16 = utf8_to_utf16_length(str8, length);
342
343 if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700344 ALOGW("Invalid string length: %zd", len16);
Steven Moreland7b06f592018-10-03 19:25:32 -0700345 return STATUS_BAD_VALUE;
346 }
347
348 status_t err = parcel->get()->writeInt32(len16);
349 if (err) {
350 return PruneStatusT(err);
351 }
352
353 void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
354 if (str16 == nullptr) {
355 return STATUS_NO_MEMORY;
356 }
357
358 utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
359
360 return STATUS_OK;
361}
362
Steven Moreland07fb9c92018-11-01 17:14:29 -0700363binder_status_t AParcel_readString(const AParcel* parcel, void* stringData,
364 AParcel_stringAllocator allocator) {
Steven Moreland7b06f592018-10-03 19:25:32 -0700365 size_t len16;
366 const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
367
368 if (str16 == nullptr) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800369 if (allocator(stringData, -1, nullptr)) {
370 return STATUS_OK;
371 }
372
Steven Moreland7b06f592018-10-03 19:25:32 -0700373 return STATUS_UNEXPECTED_NULL;
374 }
375
376 ssize_t len8;
377
378 if (len16 == 0) {
379 len8 = 1;
380 } else {
381 len8 = utf16_to_utf8_length(str16, len16) + 1;
382 }
383
Steven Moreland07fb9c92018-11-01 17:14:29 -0700384 if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700385 ALOGW("Invalid string length: %zd", len8);
Steven Moreland7b06f592018-10-03 19:25:32 -0700386 return STATUS_BAD_VALUE;
387 }
388
Steven Morelandb4e14612018-11-14 17:25:45 -0800389 char* str8;
390 bool success = allocator(stringData, len8, &str8);
Steven Moreland7b06f592018-10-03 19:25:32 -0700391
Steven Morelandb4e14612018-11-14 17:25:45 -0800392 if (!success || str8 == nullptr) {
Tomasz Wasilczyke3de8802023-11-01 11:05:27 -0700393 ALOGW("AParcel_stringAllocator failed to allocate.");
Steven Moreland7b06f592018-10-03 19:25:32 -0700394 return STATUS_NO_MEMORY;
395 }
396
397 utf16_to_utf8(str16, len16, str8, len8);
398
399 return STATUS_OK;
400}
401
Steven Morelandb4e14612018-11-14 17:25:45 -0800402binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland07fb9c92018-11-01 17:14:29 -0700403 AParcel_stringArrayElementGetter getter) {
Steven Moreland01ebcf72018-11-15 15:06:26 -0800404 // we have no clue if arrayData represents a null object or not, we can only infer from length
405 bool arrayIsNull = length < 0;
406 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
407 if (status != STATUS_OK) return status;
408 if (length <= 0) return STATUS_OK;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700409
Steven Moreland763dc4c2018-12-12 11:30:06 -0800410 for (int32_t i = 0; i < length; i++) {
411 int32_t elementLength = 0;
Steven Morelande22a9942018-12-11 18:57:05 -0800412 const char* str = getter(arrayData, i, &elementLength);
413 if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700414
Steven Morelande22a9942018-12-11 18:57:05 -0800415 binder_status_t status = AParcel_writeString(parcel, str, elementLength);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700416 if (status != STATUS_OK) return status;
417 }
418
419 return STATUS_OK;
420}
421
422// This implements AParcel_stringAllocator for a string using an array, index, and element
423// allocator.
424struct StringArrayElementAllocationAdapter {
Steven Moreland6cf66ac2018-11-02 18:14:54 -0700425 void* arrayData; // stringData from the NDK
Steven Moreland763dc4c2018-12-12 11:30:06 -0800426 int32_t index; // index into the string array
Steven Moreland07fb9c92018-11-01 17:14:29 -0700427 AParcel_stringArrayElementAllocator elementAllocator;
428
Steven Morelandb4e14612018-11-14 17:25:45 -0800429 static bool Allocator(void* stringData, int32_t length, char** buffer) {
Steven Moreland07fb9c92018-11-01 17:14:29 -0700430 StringArrayElementAllocationAdapter* adapter =
431 static_cast<StringArrayElementAllocationAdapter*>(stringData);
Steven Morelandb4e14612018-11-14 17:25:45 -0800432 return adapter->elementAllocator(adapter->arrayData, adapter->index, length, buffer);
Steven Moreland07fb9c92018-11-01 17:14:29 -0700433 }
434};
435
436binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
437 AParcel_stringArrayAllocator allocator,
438 AParcel_stringArrayElementAllocator elementAllocator) {
Steven Moreland07fb9c92018-11-01 17:14:29 -0700439 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000440 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
441 return status;
442 }
Steven Moreland07fb9c92018-11-01 17:14:29 -0700443
444 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
445
Steven Morelandb4e14612018-11-14 17:25:45 -0800446 if (length == -1) return STATUS_OK; // null string array
447
Steven Moreland07fb9c92018-11-01 17:14:29 -0700448 StringArrayElementAllocationAdapter adapter{
449 .arrayData = arrayData,
450 .index = 0,
451 .elementAllocator = elementAllocator,
452 };
453
454 for (; adapter.index < length; adapter.index++) {
Steven Morelandb4e14612018-11-14 17:25:45 -0800455 binder_status_t status = AParcel_readString(parcel, static_cast<void*>(&adapter),
456 StringArrayElementAllocationAdapter::Allocator);
457
458 if (status != STATUS_OK) return status;
Steven Moreland07fb9c92018-11-01 17:14:29 -0700459 }
460
461 return STATUS_OK;
462}
463
Steven Morelande22a9942018-12-11 18:57:05 -0800464binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
465 AParcel_writeParcelableElement elementWriter) {
466 // we have no clue if arrayData represents a null object or not, we can only infer from length
467 bool arrayIsNull = length < 0;
468 binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
469 if (status != STATUS_OK) return status;
470 if (length <= 0) return STATUS_OK;
471
Steven Moreland763dc4c2018-12-12 11:30:06 -0800472 for (int32_t i = 0; i < length; i++) {
Steven Morelande22a9942018-12-11 18:57:05 -0800473 binder_status_t status = elementWriter(parcel, arrayData, i);
474 if (status != STATUS_OK) return status;
475 }
476
477 return STATUS_OK;
478}
479
480binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
481 AParcel_parcelableArrayAllocator allocator,
482 AParcel_readParcelableElement elementReader) {
Steven Morelande22a9942018-12-11 18:57:05 -0800483 int32_t length;
Steven Morelandb3adc032021-05-14 20:41:11 +0000484 if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
485 return status;
486 }
Steven Morelande22a9942018-12-11 18:57:05 -0800487
488 if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
489
490 if (length == -1) return STATUS_OK; // null array
491
Steven Moreland763dc4c2018-12-12 11:30:06 -0800492 for (int32_t i = 0; i < length; i++) {
Steven Morelande22a9942018-12-11 18:57:05 -0800493 binder_status_t status = elementReader(parcel, arrayData, i);
494 if (status != STATUS_OK) return status;
495 }
496
497 return STATUS_OK;
498}
499
Steven Moreland2e87adc2018-08-20 19:47:00 -0700500// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
501// libbinder and this library.
502// @START
503binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700504 status_t status = parcel->get()->writeInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700505 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700506}
507
508binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700509 status_t status = parcel->get()->writeUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700510 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700511}
512
513binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700514 status_t status = parcel->get()->writeInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700515 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700516}
517
518binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700519 status_t status = parcel->get()->writeUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700520 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700521}
522
523binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700524 status_t status = parcel->get()->writeFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700525 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700526}
527
528binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700529 status_t status = parcel->get()->writeDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700530 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700531}
532
533binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700534 status_t status = parcel->get()->writeBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700535 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700536}
537
538binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700539 status_t status = parcel->get()->writeChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700540 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700541}
542
543binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700544 status_t status = parcel->get()->writeByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700545 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700546}
547
548binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700549 status_t status = parcel->get()->readInt32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700550 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700551}
552
553binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700554 status_t status = parcel->get()->readUint32(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700555 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700556}
557
558binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700559 status_t status = parcel->get()->readInt64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700560 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700561}
562
563binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700564 status_t status = parcel->get()->readUint64(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700565 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700566}
567
568binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700569 status_t status = parcel->get()->readFloat(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700570 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700571}
572
573binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700574 status_t status = parcel->get()->readDouble(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700575 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700576}
577
578binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700579 status_t status = parcel->get()->readBool(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700580 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700581}
582
583binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700584 status_t status = parcel->get()->readChar(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700585 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700586}
587
588binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
Steven Morelandf18615b2018-09-14 11:43:06 -0700589 status_t status = parcel->get()->readByte(value);
Steven Moreland5d62e442018-09-13 15:01:02 -0700590 return PruneStatusT(status);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700591}
592
Steven Moreland01ebcf72018-11-15 15:06:26 -0800593binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700594 return WriteArray<int32_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700595}
596
Steven Morelande3d09582018-11-02 19:29:36 -0700597binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* arrayData,
Steven Moreland01ebcf72018-11-15 15:06:26 -0800598 int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700599 return WriteArray<uint32_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700600}
601
Steven Moreland01ebcf72018-11-15 15:06:26 -0800602binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700603 return WriteArray<int64_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700604}
605
Steven Morelande3d09582018-11-02 19:29:36 -0700606binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* arrayData,
Steven Moreland01ebcf72018-11-15 15:06:26 -0800607 int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700608 return WriteArray<uint64_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700609}
610
Steven Moreland01ebcf72018-11-15 15:06:26 -0800611binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700612 return WriteArray<float>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700613}
614
Steven Moreland01ebcf72018-11-15 15:06:26 -0800615binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700616 return WriteArray<double>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700617}
618
Steven Moreland01ebcf72018-11-15 15:06:26 -0800619binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData, int32_t length,
Steven Moreland16e1eae2018-11-01 09:51:53 -0700620 AParcel_boolArrayGetter getter) {
621 return WriteArray<bool>(parcel, arrayData, length, getter, &Parcel::writeBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700622}
623
Steven Moreland01ebcf72018-11-15 15:06:26 -0800624binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700625 return WriteArray<char16_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700626}
627
Steven Moreland01ebcf72018-11-15 15:06:26 -0800628binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* arrayData, int32_t length) {
Steven Morelande3d09582018-11-02 19:29:36 -0700629 return WriteArray<int8_t>(parcel, arrayData, length);
Steven Morelanda8845662018-10-12 11:53:03 -0700630}
631
Steven Moreland71872f82018-10-29 11:46:56 -0700632binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700633 AParcel_int32ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700634 return ReadArray<int32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700635}
636
Steven Moreland71872f82018-10-29 11:46:56 -0700637binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700638 AParcel_uint32ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700639 return ReadArray<uint32_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700640}
641
Steven Moreland71872f82018-10-29 11:46:56 -0700642binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700643 AParcel_int64ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700644 return ReadArray<int64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700645}
646
Steven Moreland71872f82018-10-29 11:46:56 -0700647binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700648 AParcel_uint64ArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700649 return ReadArray<uint64_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700650}
651
Steven Moreland71872f82018-10-29 11:46:56 -0700652binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700653 AParcel_floatArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700654 return ReadArray<float>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700655}
656
Steven Moreland71872f82018-10-29 11:46:56 -0700657binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700658 AParcel_doubleArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700659 return ReadArray<double>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700660}
661
Steven Moreland71872f82018-10-29 11:46:56 -0700662binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700663 AParcel_boolArrayAllocator allocator,
Steven Morelanda8845662018-10-12 11:53:03 -0700664 AParcel_boolArraySetter setter) {
Steven Moreland71872f82018-10-29 11:46:56 -0700665 return ReadArray<bool>(parcel, arrayData, allocator, setter, &Parcel::readBool);
Steven Morelanda8845662018-10-12 11:53:03 -0700666}
667
Steven Moreland71872f82018-10-29 11:46:56 -0700668binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700669 AParcel_charArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700670 return ReadArray<char16_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700671}
672
Steven Moreland71872f82018-10-29 11:46:56 -0700673binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
Steven Moreland9ac9dca2018-11-01 10:07:31 -0700674 AParcel_byteArrayAllocator allocator) {
Steven Moreland71872f82018-10-29 11:46:56 -0700675 return ReadArray<int8_t>(parcel, arrayData, allocator);
Steven Morelanda8845662018-10-12 11:53:03 -0700676}
677
John Reck79fb24b2020-02-14 13:56:19 -0800678bool AParcel_getAllowFds(const AParcel* parcel) {
679 return parcel->get()->allowFds();
680}
681
Jeongik Cha62240b92020-10-14 00:06:01 +0900682binder_status_t AParcel_reset(AParcel* parcel) {
683 parcel->get()->freeData();
684 return STATUS_OK;
685}
686
687int32_t AParcel_getDataSize(const AParcel* parcel) {
688 return parcel->get()->dataSize();
689}
690
691binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) {
692 status_t status = to->get()->appendFrom(from->get(), start, size);
693 return PruneStatusT(status);
694}
695
696AParcel* AParcel_create() {
697 return new AParcel(nullptr);
698}
699
Yu Shanfb39f9c2021-08-25 14:58:09 -0700700binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len) {
701 if (parcel->get()->objectsCount()) {
702 return STATUS_INVALID_OPERATION;
703 }
Pawan Waghd886a442023-01-21 02:16:38 +0000704 // b/264739302 - getDataSize will return dataPos if it is greater than dataSize
705 // which will cause crashes in memcpy at later point. Instead compare with
706 // actual length of internal buffer
707 int32_t dataSize = parcel->get()->dataBufferSize();
Yu Shanfb39f9c2021-08-25 14:58:09 -0700708 if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
709 return STATUS_BAD_VALUE;
710 }
711 const uint8_t* internalBuffer = parcel->get()->data();
Pawan Wagh0beb9562023-01-20 19:11:39 +0000712 if (internalBuffer == nullptr) {
713 return STATUS_UNEXPECTED_NULL;
714 }
Yu Shanfb39f9c2021-08-25 14:58:09 -0700715 memcpy(buffer, internalBuffer + start, len);
716 return STATUS_OK;
717}
718
719binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len) {
720 status_t status = parcel->get()->setDataSize(len);
721 if (status != ::android::OK) {
722 return PruneStatusT(status);
723 }
724 parcel->get()->setDataPosition(0);
725
726 void* raw = parcel->get()->writeInplace(len);
727 if (raw == nullptr) {
728 return STATUS_NO_MEMORY;
729 }
730 memcpy(raw, buffer, len);
731 return STATUS_OK;
732}
733
Steven Moreland2e87adc2018-08-20 19:47:00 -0700734// @END