xref: /aosp_15_r20/frameworks/native/libs/binder/ndk/parcel.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_parcel.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <android/binder_parcel_platform.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/ParcelFileDescriptor.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/unique_fd.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <utils/Unicode.h>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include <limits>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include "ibinder_internal.h"
28*38e8c45fSAndroid Build Coastguard Worker #include "parcel_internal.h"
29*38e8c45fSAndroid Build Coastguard Worker #include "status_internal.h"
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker using ::android::IBinder;
32*38e8c45fSAndroid Build Coastguard Worker using ::android::Parcel;
33*38e8c45fSAndroid Build Coastguard Worker using ::android::sp;
34*38e8c45fSAndroid Build Coastguard Worker using ::android::status_t;
35*38e8c45fSAndroid Build Coastguard Worker using ::android::binder::unique_fd;
36*38e8c45fSAndroid Build Coastguard Worker using ::android::os::ParcelFileDescriptor;
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker template <typename T>
39*38e8c45fSAndroid Build Coastguard Worker using ContiguousArrayAllocator = bool (*)(void* arrayData, int32_t length, T** outBuffer);
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker template <typename T>
42*38e8c45fSAndroid Build Coastguard Worker using ArrayAllocator = bool (*)(void* arrayData, int32_t length);
43*38e8c45fSAndroid Build Coastguard Worker template <typename T>
44*38e8c45fSAndroid Build Coastguard Worker using ArrayGetter = T (*)(const void* arrayData, size_t index);
45*38e8c45fSAndroid Build Coastguard Worker template <typename T>
46*38e8c45fSAndroid Build Coastguard Worker using ArraySetter = void (*)(void* arrayData, size_t index, T value);
47*38e8c45fSAndroid Build Coastguard Worker 
WriteAndValidateArraySize(AParcel * parcel,bool isNullArray,int32_t length)48*38e8c45fSAndroid Build Coastguard Worker static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
49*38e8c45fSAndroid Build Coastguard Worker                                                  int32_t length) {
50*38e8c45fSAndroid Build Coastguard Worker     // only -1 can be used to represent a null array
51*38e8c45fSAndroid Build Coastguard Worker     if (length < -1) return STATUS_BAD_VALUE;
52*38e8c45fSAndroid Build Coastguard Worker 
53*38e8c45fSAndroid Build Coastguard Worker     if (!isNullArray && length < 0) {
54*38e8c45fSAndroid Build Coastguard Worker         ALOGE("non-null array but length is %" PRIi32, length);
55*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
56*38e8c45fSAndroid Build Coastguard Worker     }
57*38e8c45fSAndroid Build Coastguard Worker     if (isNullArray && length > 0) {
58*38e8c45fSAndroid Build Coastguard Worker         ALOGE("null buffer cannot be for size %" PRIi32 " array.", length);
59*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
60*38e8c45fSAndroid Build Coastguard Worker     }
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker     Parcel* rawParcel = parcel->get();
63*38e8c45fSAndroid Build Coastguard Worker 
64*38e8c45fSAndroid Build Coastguard Worker     status_t status = rawParcel->writeInt32(length);
65*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return PruneStatusT(status);
66*38e8c45fSAndroid Build Coastguard Worker 
67*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
68*38e8c45fSAndroid Build Coastguard Worker }
69*38e8c45fSAndroid Build Coastguard Worker 
ReadAndValidateArraySize(const AParcel * parcel,int32_t * length)70*38e8c45fSAndroid Build Coastguard Worker static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
71*38e8c45fSAndroid Build Coastguard Worker     if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
72*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(status);
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker     if (*length < -1) return STATUS_BAD_VALUE;  // libbinder_ndk reserves these
76*38e8c45fSAndroid Build Coastguard Worker     if (*length <= 0) return STATUS_OK;         // null
77*38e8c45fSAndroid Build Coastguard Worker     if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
80*38e8c45fSAndroid Build Coastguard Worker }
81*38e8c45fSAndroid Build Coastguard Worker 
82*38e8c45fSAndroid Build Coastguard Worker template <typename T>
WriteArray(AParcel * parcel,const T * array,int32_t length)83*38e8c45fSAndroid Build Coastguard Worker binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
84*38e8c45fSAndroid Build Coastguard Worker     binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
85*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return status;
86*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     int32_t size = 0;
89*38e8c45fSAndroid Build Coastguard Worker     if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
90*38e8c45fSAndroid Build Coastguard Worker 
91*38e8c45fSAndroid Build Coastguard Worker     void* const data = parcel->get()->writeInplace(size);
92*38e8c45fSAndroid Build Coastguard Worker     if (data == nullptr) return STATUS_NO_MEMORY;
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker     memcpy(data, array, size);
95*38e8c45fSAndroid Build Coastguard Worker 
96*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
97*38e8c45fSAndroid Build Coastguard Worker }
98*38e8c45fSAndroid Build Coastguard Worker 
99*38e8c45fSAndroid Build Coastguard Worker // Each element in a char16_t array is converted to an int32_t (not packed).
100*38e8c45fSAndroid Build Coastguard Worker template <>
WriteArray(AParcel * parcel,const char16_t * array,int32_t length)101*38e8c45fSAndroid Build Coastguard Worker binder_status_t WriteArray<char16_t>(AParcel* parcel, const char16_t* array, int32_t length) {
102*38e8c45fSAndroid Build Coastguard Worker     binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
103*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return status;
104*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
105*38e8c45fSAndroid Build Coastguard Worker 
106*38e8c45fSAndroid Build Coastguard Worker     int32_t size = 0;
107*38e8c45fSAndroid Build Coastguard Worker     if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     Parcel* rawParcel = parcel->get();
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
112*38e8c45fSAndroid Build Coastguard Worker         status = rawParcel->writeChar(array[i]);
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return PruneStatusT(status);
115*38e8c45fSAndroid Build Coastguard Worker     }
116*38e8c45fSAndroid Build Coastguard Worker 
117*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
118*38e8c45fSAndroid Build Coastguard Worker }
119*38e8c45fSAndroid Build Coastguard Worker 
120*38e8c45fSAndroid Build Coastguard Worker template <typename T>
ReadArray(const AParcel * parcel,void * arrayData,ContiguousArrayAllocator<T> allocator)121*38e8c45fSAndroid Build Coastguard Worker binder_status_t ReadArray(const AParcel* parcel, void* arrayData,
122*38e8c45fSAndroid Build Coastguard Worker                           ContiguousArrayAllocator<T> allocator) {
123*38e8c45fSAndroid Build Coastguard Worker     const Parcel* rawParcel = parcel->get();
124*38e8c45fSAndroid Build Coastguard Worker 
125*38e8c45fSAndroid Build Coastguard Worker     int32_t length;
126*38e8c45fSAndroid Build Coastguard Worker     if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
127*38e8c45fSAndroid Build Coastguard Worker         return status;
128*38e8c45fSAndroid Build Coastguard Worker     }
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker     T* array;
131*38e8c45fSAndroid Build Coastguard Worker     if (!allocator(arrayData, length, &array)) {
132*38e8c45fSAndroid Build Coastguard Worker         if (length < 0) {
133*38e8c45fSAndroid Build Coastguard Worker             return STATUS_UNEXPECTED_NULL;
134*38e8c45fSAndroid Build Coastguard Worker         } else {
135*38e8c45fSAndroid Build Coastguard Worker             return STATUS_NO_MEMORY;
136*38e8c45fSAndroid Build Coastguard Worker         }
137*38e8c45fSAndroid Build Coastguard Worker     }
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
140*38e8c45fSAndroid Build Coastguard Worker     if (array == nullptr) return STATUS_NO_MEMORY;
141*38e8c45fSAndroid Build Coastguard Worker 
142*38e8c45fSAndroid Build Coastguard Worker     int32_t size = 0;
143*38e8c45fSAndroid Build Coastguard Worker     if (__builtin_smul_overflow(sizeof(T), length, &size)) return STATUS_NO_MEMORY;
144*38e8c45fSAndroid Build Coastguard Worker 
145*38e8c45fSAndroid Build Coastguard Worker     const void* data = rawParcel->readInplace(size);
146*38e8c45fSAndroid Build Coastguard Worker     if (data == nullptr) return STATUS_NO_MEMORY;
147*38e8c45fSAndroid Build Coastguard Worker 
148*38e8c45fSAndroid Build Coastguard Worker     memcpy(array, data, size);
149*38e8c45fSAndroid Build Coastguard Worker 
150*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
151*38e8c45fSAndroid Build Coastguard Worker }
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker // Each element in a char16_t array is converted to an int32_t (not packed)
154*38e8c45fSAndroid Build Coastguard Worker template <>
ReadArray(const AParcel * parcel,void * arrayData,ContiguousArrayAllocator<char16_t> allocator)155*38e8c45fSAndroid Build Coastguard Worker binder_status_t ReadArray<char16_t>(const AParcel* parcel, void* arrayData,
156*38e8c45fSAndroid Build Coastguard Worker                                     ContiguousArrayAllocator<char16_t> allocator) {
157*38e8c45fSAndroid Build Coastguard Worker     const Parcel* rawParcel = parcel->get();
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker     int32_t length;
160*38e8c45fSAndroid Build Coastguard Worker     if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
161*38e8c45fSAndroid Build Coastguard Worker         return status;
162*38e8c45fSAndroid Build Coastguard Worker     }
163*38e8c45fSAndroid Build Coastguard Worker 
164*38e8c45fSAndroid Build Coastguard Worker     char16_t* array;
165*38e8c45fSAndroid Build Coastguard Worker     if (!allocator(arrayData, length, &array)) {
166*38e8c45fSAndroid Build Coastguard Worker         if (length < 0) {
167*38e8c45fSAndroid Build Coastguard Worker             return STATUS_UNEXPECTED_NULL;
168*38e8c45fSAndroid Build Coastguard Worker         } else {
169*38e8c45fSAndroid Build Coastguard Worker             return STATUS_NO_MEMORY;
170*38e8c45fSAndroid Build Coastguard Worker         }
171*38e8c45fSAndroid Build Coastguard Worker     }
172*38e8c45fSAndroid Build Coastguard Worker 
173*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
174*38e8c45fSAndroid Build Coastguard Worker     if (array == nullptr) return STATUS_NO_MEMORY;
175*38e8c45fSAndroid Build Coastguard Worker 
176*38e8c45fSAndroid Build Coastguard Worker     int32_t size = 0;
177*38e8c45fSAndroid Build Coastguard Worker     if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
178*38e8c45fSAndroid Build Coastguard Worker 
179*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
180*38e8c45fSAndroid Build Coastguard Worker         status_t status = rawParcel->readChar(array + i);
181*38e8c45fSAndroid Build Coastguard Worker 
182*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return PruneStatusT(status);
183*38e8c45fSAndroid Build Coastguard Worker     }
184*38e8c45fSAndroid Build Coastguard Worker 
185*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
186*38e8c45fSAndroid Build Coastguard Worker }
187*38e8c45fSAndroid Build Coastguard Worker 
188*38e8c45fSAndroid Build Coastguard Worker template <typename T>
WriteArray(AParcel * parcel,const void * arrayData,int32_t length,ArrayGetter<T> getter,status_t (Parcel::* write)(T))189*38e8c45fSAndroid Build Coastguard Worker binder_status_t WriteArray(AParcel* parcel, const void* arrayData, int32_t length,
190*38e8c45fSAndroid Build Coastguard Worker                            ArrayGetter<T> getter, status_t (Parcel::*write)(T)) {
191*38e8c45fSAndroid Build Coastguard Worker     // we have no clue if arrayData represents a null object or not, we can only infer from length
192*38e8c45fSAndroid Build Coastguard Worker     bool arrayIsNull = length < 0;
193*38e8c45fSAndroid Build Coastguard Worker     binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
194*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return status;
195*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker     Parcel* rawParcel = parcel->get();
198*38e8c45fSAndroid Build Coastguard Worker 
199*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
200*38e8c45fSAndroid Build Coastguard Worker         status = (rawParcel->*write)(getter(arrayData, i));
201*38e8c45fSAndroid Build Coastguard Worker 
202*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return PruneStatusT(status);
203*38e8c45fSAndroid Build Coastguard Worker     }
204*38e8c45fSAndroid Build Coastguard Worker 
205*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
206*38e8c45fSAndroid Build Coastguard Worker }
207*38e8c45fSAndroid Build Coastguard Worker 
208*38e8c45fSAndroid Build Coastguard Worker template <typename T>
ReadArray(const AParcel * parcel,void * arrayData,ArrayAllocator<T> allocator,ArraySetter<T> setter,status_t (Parcel::* read)(T *)const)209*38e8c45fSAndroid Build Coastguard Worker binder_status_t ReadArray(const AParcel* parcel, void* arrayData, ArrayAllocator<T> allocator,
210*38e8c45fSAndroid Build Coastguard Worker                           ArraySetter<T> setter, status_t (Parcel::*read)(T*) const) {
211*38e8c45fSAndroid Build Coastguard Worker     const Parcel* rawParcel = parcel->get();
212*38e8c45fSAndroid Build Coastguard Worker 
213*38e8c45fSAndroid Build Coastguard Worker     int32_t length;
214*38e8c45fSAndroid Build Coastguard Worker     if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
215*38e8c45fSAndroid Build Coastguard Worker         return status;
216*38e8c45fSAndroid Build Coastguard Worker     }
217*38e8c45fSAndroid Build Coastguard Worker 
218*38e8c45fSAndroid Build Coastguard Worker     if (!allocator(arrayData, length)) {
219*38e8c45fSAndroid Build Coastguard Worker         if (length < 0) {
220*38e8c45fSAndroid Build Coastguard Worker             return STATUS_UNEXPECTED_NULL;
221*38e8c45fSAndroid Build Coastguard Worker         } else {
222*38e8c45fSAndroid Build Coastguard Worker             return STATUS_NO_MEMORY;
223*38e8c45fSAndroid Build Coastguard Worker         }
224*38e8c45fSAndroid Build Coastguard Worker     }
225*38e8c45fSAndroid Build Coastguard Worker 
226*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
227*38e8c45fSAndroid Build Coastguard Worker 
228*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
229*38e8c45fSAndroid Build Coastguard Worker         T readTarget;
230*38e8c45fSAndroid Build Coastguard Worker         status_t status = (rawParcel->*read)(&readTarget);
231*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return PruneStatusT(status);
232*38e8c45fSAndroid Build Coastguard Worker 
233*38e8c45fSAndroid Build Coastguard Worker         setter(arrayData, i, readTarget);
234*38e8c45fSAndroid Build Coastguard Worker     }
235*38e8c45fSAndroid Build Coastguard Worker 
236*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
237*38e8c45fSAndroid Build Coastguard Worker }
238*38e8c45fSAndroid Build Coastguard Worker 
AParcel_delete(AParcel * parcel)239*38e8c45fSAndroid Build Coastguard Worker void AParcel_delete(AParcel* parcel) {
240*38e8c45fSAndroid Build Coastguard Worker     delete parcel;
241*38e8c45fSAndroid Build Coastguard Worker }
242*38e8c45fSAndroid Build Coastguard Worker 
AParcel_setDataPosition(const AParcel * parcel,int32_t position)243*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
244*38e8c45fSAndroid Build Coastguard Worker     if (position < 0) {
245*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
246*38e8c45fSAndroid Build Coastguard Worker     }
247*38e8c45fSAndroid Build Coastguard Worker 
248*38e8c45fSAndroid Build Coastguard Worker     parcel->get()->setDataPosition(position);
249*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
250*38e8c45fSAndroid Build Coastguard Worker }
251*38e8c45fSAndroid Build Coastguard Worker 
AParcel_getDataPosition(const AParcel * parcel)252*38e8c45fSAndroid Build Coastguard Worker int32_t AParcel_getDataPosition(const AParcel* parcel) {
253*38e8c45fSAndroid Build Coastguard Worker     return parcel->get()->dataPosition();
254*38e8c45fSAndroid Build Coastguard Worker }
255*38e8c45fSAndroid Build Coastguard Worker 
AParcel_markSensitive(const AParcel * parcel)256*38e8c45fSAndroid Build Coastguard Worker void AParcel_markSensitive(const AParcel* parcel) {
257*38e8c45fSAndroid Build Coastguard Worker     return parcel->get()->markSensitive();
258*38e8c45fSAndroid Build Coastguard Worker }
259*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeStrongBinder(AParcel * parcel,AIBinder * binder)260*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
261*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
262*38e8c45fSAndroid Build Coastguard Worker     return parcel->get()->writeStrongBinder(writeBinder);
263*38e8c45fSAndroid Build Coastguard Worker }
AParcel_readStrongBinder(const AParcel * parcel,AIBinder ** binder)264*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
265*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> readBinder = nullptr;
266*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readNullableStrongBinder(&readBinder);
267*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) {
268*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(status);
269*38e8c45fSAndroid Build Coastguard Worker     }
270*38e8c45fSAndroid Build Coastguard Worker     sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(readBinder);
271*38e8c45fSAndroid Build Coastguard Worker     AIBinder_incStrong(ret.get());
272*38e8c45fSAndroid Build Coastguard Worker 
273*38e8c45fSAndroid Build Coastguard Worker     if (ret.get() != nullptr && parcel->get()->isServiceFuzzing()) {
274*38e8c45fSAndroid Build Coastguard Worker         if (auto bp = ret->asABpBinder(); bp != nullptr) {
275*38e8c45fSAndroid Build Coastguard Worker             bp->setServiceFuzzing();
276*38e8c45fSAndroid Build Coastguard Worker         }
277*38e8c45fSAndroid Build Coastguard Worker     }
278*38e8c45fSAndroid Build Coastguard Worker 
279*38e8c45fSAndroid Build Coastguard Worker     *binder = ret.get();
280*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
281*38e8c45fSAndroid Build Coastguard Worker }
282*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeParcelFileDescriptor(AParcel * parcel,int fd)283*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
284*38e8c45fSAndroid Build Coastguard Worker     if (fd < 0) {
285*38e8c45fSAndroid Build Coastguard Worker         if (fd != -1) {
286*38e8c45fSAndroid Build Coastguard Worker             return STATUS_UNKNOWN_ERROR;
287*38e8c45fSAndroid Build Coastguard Worker         }
288*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(parcel->get()->writeInt32(0));  // null
289*38e8c45fSAndroid Build Coastguard Worker     }
290*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeInt32(1);  // not-null
291*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return PruneStatusT(status);
292*38e8c45fSAndroid Build Coastguard Worker 
293*38e8c45fSAndroid Build Coastguard Worker     status = parcel->get()->writeDupParcelFileDescriptor(fd);
294*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
295*38e8c45fSAndroid Build Coastguard Worker }
296*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readParcelFileDescriptor(const AParcel * parcel,int * fd)297*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
298*38e8c45fSAndroid Build Coastguard Worker     std::optional<ParcelFileDescriptor> parcelFd;
299*38e8c45fSAndroid Build Coastguard Worker 
300*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readParcelable(&parcelFd);
301*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return PruneStatusT(status);
302*38e8c45fSAndroid Build Coastguard Worker 
303*38e8c45fSAndroid Build Coastguard Worker     if (parcelFd) {
304*38e8c45fSAndroid Build Coastguard Worker         *fd = parcelFd->release().release();
305*38e8c45fSAndroid Build Coastguard Worker     } else {
306*38e8c45fSAndroid Build Coastguard Worker         *fd = -1;
307*38e8c45fSAndroid Build Coastguard Worker     }
308*38e8c45fSAndroid Build Coastguard Worker 
309*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
310*38e8c45fSAndroid Build Coastguard Worker }
311*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeStatusHeader(AParcel * parcel,const AStatus * status)312*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) {
313*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status->get().writeToParcel(parcel->get()));
314*38e8c45fSAndroid Build Coastguard Worker }
AParcel_readStatusHeader(const AParcel * parcel,AStatus ** status)315*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readStatusHeader(const AParcel* parcel, AStatus** status) {
316*38e8c45fSAndroid Build Coastguard Worker     ::android::binder::Status bstatus;
317*38e8c45fSAndroid Build Coastguard Worker     binder_status_t ret = PruneStatusT(bstatus.readFromParcel(*parcel->get()));
318*38e8c45fSAndroid Build Coastguard Worker     if (ret == STATUS_OK) {
319*38e8c45fSAndroid Build Coastguard Worker         *status = new AStatus(std::move(bstatus));
320*38e8c45fSAndroid Build Coastguard Worker     }
321*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(ret);
322*38e8c45fSAndroid Build Coastguard Worker }
323*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeString(AParcel * parcel,const char * string,int32_t length)324*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeString(AParcel* parcel, const char* string, int32_t length) {
325*38e8c45fSAndroid Build Coastguard Worker     if (string == nullptr) {
326*38e8c45fSAndroid Build Coastguard Worker         if (length != -1) {
327*38e8c45fSAndroid Build Coastguard Worker             ALOGW("null string must be used with length == -1.");
328*38e8c45fSAndroid Build Coastguard Worker             return STATUS_BAD_VALUE;
329*38e8c45fSAndroid Build Coastguard Worker         }
330*38e8c45fSAndroid Build Coastguard Worker 
331*38e8c45fSAndroid Build Coastguard Worker         status_t err = parcel->get()->writeInt32(-1);
332*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(err);
333*38e8c45fSAndroid Build Coastguard Worker     }
334*38e8c45fSAndroid Build Coastguard Worker 
335*38e8c45fSAndroid Build Coastguard Worker     if (length < 0) {
336*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Negative string length: %" PRIi32, length);
337*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
338*38e8c45fSAndroid Build Coastguard Worker     }
339*38e8c45fSAndroid Build Coastguard Worker 
340*38e8c45fSAndroid Build Coastguard Worker     const uint8_t* str8 = (uint8_t*)string;
341*38e8c45fSAndroid Build Coastguard Worker     const ssize_t len16 = utf8_to_utf16_length(str8, length);
342*38e8c45fSAndroid Build Coastguard Worker 
343*38e8c45fSAndroid Build Coastguard Worker     if (len16 < 0 || len16 >= std::numeric_limits<int32_t>::max()) {
344*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Invalid string length: %zd", len16);
345*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
346*38e8c45fSAndroid Build Coastguard Worker     }
347*38e8c45fSAndroid Build Coastguard Worker 
348*38e8c45fSAndroid Build Coastguard Worker     status_t err = parcel->get()->writeInt32(len16);
349*38e8c45fSAndroid Build Coastguard Worker     if (err) {
350*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(err);
351*38e8c45fSAndroid Build Coastguard Worker     }
352*38e8c45fSAndroid Build Coastguard Worker 
353*38e8c45fSAndroid Build Coastguard Worker     void* str16 = parcel->get()->writeInplace((len16 + 1) * sizeof(char16_t));
354*38e8c45fSAndroid Build Coastguard Worker     if (str16 == nullptr) {
355*38e8c45fSAndroid Build Coastguard Worker         return STATUS_NO_MEMORY;
356*38e8c45fSAndroid Build Coastguard Worker     }
357*38e8c45fSAndroid Build Coastguard Worker 
358*38e8c45fSAndroid Build Coastguard Worker     utf8_to_utf16(str8, length, (char16_t*)str16, (size_t)len16 + 1);
359*38e8c45fSAndroid Build Coastguard Worker 
360*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
361*38e8c45fSAndroid Build Coastguard Worker }
362*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readString(const AParcel * parcel,void * stringData,AParcel_stringAllocator allocator)363*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readString(const AParcel* parcel, void* stringData,
364*38e8c45fSAndroid Build Coastguard Worker                                    AParcel_stringAllocator allocator) {
365*38e8c45fSAndroid Build Coastguard Worker     size_t len16;
366*38e8c45fSAndroid Build Coastguard Worker     const char16_t* str16 = parcel->get()->readString16Inplace(&len16);
367*38e8c45fSAndroid Build Coastguard Worker 
368*38e8c45fSAndroid Build Coastguard Worker     if (str16 == nullptr) {
369*38e8c45fSAndroid Build Coastguard Worker         if (allocator(stringData, -1, nullptr)) {
370*38e8c45fSAndroid Build Coastguard Worker             return STATUS_OK;
371*38e8c45fSAndroid Build Coastguard Worker         }
372*38e8c45fSAndroid Build Coastguard Worker 
373*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
374*38e8c45fSAndroid Build Coastguard Worker     }
375*38e8c45fSAndroid Build Coastguard Worker 
376*38e8c45fSAndroid Build Coastguard Worker     ssize_t len8;
377*38e8c45fSAndroid Build Coastguard Worker 
378*38e8c45fSAndroid Build Coastguard Worker     if (len16 == 0) {
379*38e8c45fSAndroid Build Coastguard Worker         len8 = 1;
380*38e8c45fSAndroid Build Coastguard Worker     } else {
381*38e8c45fSAndroid Build Coastguard Worker         len8 = utf16_to_utf8_length(str16, len16) + 1;
382*38e8c45fSAndroid Build Coastguard Worker     }
383*38e8c45fSAndroid Build Coastguard Worker 
384*38e8c45fSAndroid Build Coastguard Worker     if (len8 <= 0 || len8 > std::numeric_limits<int32_t>::max()) {
385*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Invalid string length: %zd", len8);
386*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
387*38e8c45fSAndroid Build Coastguard Worker     }
388*38e8c45fSAndroid Build Coastguard Worker 
389*38e8c45fSAndroid Build Coastguard Worker     char* str8;
390*38e8c45fSAndroid Build Coastguard Worker     bool success = allocator(stringData, len8, &str8);
391*38e8c45fSAndroid Build Coastguard Worker 
392*38e8c45fSAndroid Build Coastguard Worker     if (!success || str8 == nullptr) {
393*38e8c45fSAndroid Build Coastguard Worker         ALOGW("AParcel_stringAllocator failed to allocate.");
394*38e8c45fSAndroid Build Coastguard Worker         return STATUS_NO_MEMORY;
395*38e8c45fSAndroid Build Coastguard Worker     }
396*38e8c45fSAndroid Build Coastguard Worker 
397*38e8c45fSAndroid Build Coastguard Worker     utf16_to_utf8(str16, len16, str8, len8);
398*38e8c45fSAndroid Build Coastguard Worker 
399*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
400*38e8c45fSAndroid Build Coastguard Worker }
401*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeStringArray(AParcel * parcel,const void * arrayData,int32_t length,AParcel_stringArrayElementGetter getter)402*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeStringArray(AParcel* parcel, const void* arrayData, int32_t length,
403*38e8c45fSAndroid Build Coastguard Worker                                          AParcel_stringArrayElementGetter getter) {
404*38e8c45fSAndroid Build Coastguard Worker     // we have no clue if arrayData represents a null object or not, we can only infer from length
405*38e8c45fSAndroid Build Coastguard Worker     bool arrayIsNull = length < 0;
406*38e8c45fSAndroid Build Coastguard Worker     binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
407*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return status;
408*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
409*38e8c45fSAndroid Build Coastguard Worker 
410*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
411*38e8c45fSAndroid Build Coastguard Worker         int32_t elementLength = 0;
412*38e8c45fSAndroid Build Coastguard Worker         const char* str = getter(arrayData, i, &elementLength);
413*38e8c45fSAndroid Build Coastguard Worker         if (str == nullptr && elementLength != -1) return STATUS_BAD_VALUE;
414*38e8c45fSAndroid Build Coastguard Worker 
415*38e8c45fSAndroid Build Coastguard Worker         binder_status_t status = AParcel_writeString(parcel, str, elementLength);
416*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return status;
417*38e8c45fSAndroid Build Coastguard Worker     }
418*38e8c45fSAndroid Build Coastguard Worker 
419*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
420*38e8c45fSAndroid Build Coastguard Worker }
421*38e8c45fSAndroid Build Coastguard Worker 
422*38e8c45fSAndroid Build Coastguard Worker // This implements AParcel_stringAllocator for a string using an array, index, and element
423*38e8c45fSAndroid Build Coastguard Worker // allocator.
424*38e8c45fSAndroid Build Coastguard Worker struct StringArrayElementAllocationAdapter {
425*38e8c45fSAndroid Build Coastguard Worker     void* arrayData;  // stringData from the NDK
426*38e8c45fSAndroid Build Coastguard Worker     int32_t index;    // index into the string array
427*38e8c45fSAndroid Build Coastguard Worker     AParcel_stringArrayElementAllocator elementAllocator;
428*38e8c45fSAndroid Build Coastguard Worker 
AllocatorStringArrayElementAllocationAdapter429*38e8c45fSAndroid Build Coastguard Worker     static bool Allocator(void* stringData, int32_t length, char** buffer) {
430*38e8c45fSAndroid Build Coastguard Worker         StringArrayElementAllocationAdapter* adapter =
431*38e8c45fSAndroid Build Coastguard Worker                 static_cast<StringArrayElementAllocationAdapter*>(stringData);
432*38e8c45fSAndroid Build Coastguard Worker         return adapter->elementAllocator(adapter->arrayData, adapter->index, length, buffer);
433*38e8c45fSAndroid Build Coastguard Worker     }
434*38e8c45fSAndroid Build Coastguard Worker };
435*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readStringArray(const AParcel * parcel,void * arrayData,AParcel_stringArrayAllocator allocator,AParcel_stringArrayElementAllocator elementAllocator)436*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
437*38e8c45fSAndroid Build Coastguard Worker                                         AParcel_stringArrayAllocator allocator,
438*38e8c45fSAndroid Build Coastguard Worker                                         AParcel_stringArrayElementAllocator elementAllocator) {
439*38e8c45fSAndroid Build Coastguard Worker     int32_t length;
440*38e8c45fSAndroid Build Coastguard Worker     if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
441*38e8c45fSAndroid Build Coastguard Worker         return status;
442*38e8c45fSAndroid Build Coastguard Worker     }
443*38e8c45fSAndroid Build Coastguard Worker 
444*38e8c45fSAndroid Build Coastguard Worker     if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
445*38e8c45fSAndroid Build Coastguard Worker 
446*38e8c45fSAndroid Build Coastguard Worker     if (length == -1) return STATUS_OK;  // null string array
447*38e8c45fSAndroid Build Coastguard Worker 
448*38e8c45fSAndroid Build Coastguard Worker     StringArrayElementAllocationAdapter adapter{
449*38e8c45fSAndroid Build Coastguard Worker             .arrayData = arrayData,
450*38e8c45fSAndroid Build Coastguard Worker             .index = 0,
451*38e8c45fSAndroid Build Coastguard Worker             .elementAllocator = elementAllocator,
452*38e8c45fSAndroid Build Coastguard Worker     };
453*38e8c45fSAndroid Build Coastguard Worker 
454*38e8c45fSAndroid Build Coastguard Worker     for (; adapter.index < length; adapter.index++) {
455*38e8c45fSAndroid Build Coastguard Worker         binder_status_t status = AParcel_readString(parcel, static_cast<void*>(&adapter),
456*38e8c45fSAndroid Build Coastguard Worker                                                     StringArrayElementAllocationAdapter::Allocator);
457*38e8c45fSAndroid Build Coastguard Worker 
458*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return status;
459*38e8c45fSAndroid Build Coastguard Worker     }
460*38e8c45fSAndroid Build Coastguard Worker 
461*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
462*38e8c45fSAndroid Build Coastguard Worker }
463*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeParcelableArray(AParcel * parcel,const void * arrayData,int32_t length,AParcel_writeParcelableElement elementWriter)464*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeParcelableArray(AParcel* parcel, const void* arrayData, int32_t length,
465*38e8c45fSAndroid Build Coastguard Worker                                              AParcel_writeParcelableElement elementWriter) {
466*38e8c45fSAndroid Build Coastguard Worker     // we have no clue if arrayData represents a null object or not, we can only infer from length
467*38e8c45fSAndroid Build Coastguard Worker     bool arrayIsNull = length < 0;
468*38e8c45fSAndroid Build Coastguard Worker     binder_status_t status = WriteAndValidateArraySize(parcel, arrayIsNull, length);
469*38e8c45fSAndroid Build Coastguard Worker     if (status != STATUS_OK) return status;
470*38e8c45fSAndroid Build Coastguard Worker     if (length <= 0) return STATUS_OK;
471*38e8c45fSAndroid Build Coastguard Worker 
472*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
473*38e8c45fSAndroid Build Coastguard Worker         binder_status_t status = elementWriter(parcel, arrayData, i);
474*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return status;
475*38e8c45fSAndroid Build Coastguard Worker     }
476*38e8c45fSAndroid Build Coastguard Worker 
477*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
478*38e8c45fSAndroid Build Coastguard Worker }
479*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readParcelableArray(const AParcel * parcel,void * arrayData,AParcel_parcelableArrayAllocator allocator,AParcel_readParcelableElement elementReader)480*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
481*38e8c45fSAndroid Build Coastguard Worker                                             AParcel_parcelableArrayAllocator allocator,
482*38e8c45fSAndroid Build Coastguard Worker                                             AParcel_readParcelableElement elementReader) {
483*38e8c45fSAndroid Build Coastguard Worker     int32_t length;
484*38e8c45fSAndroid Build Coastguard Worker     if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
485*38e8c45fSAndroid Build Coastguard Worker         return status;
486*38e8c45fSAndroid Build Coastguard Worker     }
487*38e8c45fSAndroid Build Coastguard Worker 
488*38e8c45fSAndroid Build Coastguard Worker     if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
489*38e8c45fSAndroid Build Coastguard Worker 
490*38e8c45fSAndroid Build Coastguard Worker     if (length == -1) return STATUS_OK;  // null array
491*38e8c45fSAndroid Build Coastguard Worker 
492*38e8c45fSAndroid Build Coastguard Worker     for (int32_t i = 0; i < length; i++) {
493*38e8c45fSAndroid Build Coastguard Worker         binder_status_t status = elementReader(parcel, arrayData, i);
494*38e8c45fSAndroid Build Coastguard Worker         if (status != STATUS_OK) return status;
495*38e8c45fSAndroid Build Coastguard Worker     }
496*38e8c45fSAndroid Build Coastguard Worker 
497*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
498*38e8c45fSAndroid Build Coastguard Worker }
499*38e8c45fSAndroid Build Coastguard Worker 
500*38e8c45fSAndroid Build Coastguard Worker // See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
501*38e8c45fSAndroid Build Coastguard Worker // libbinder and this library.
502*38e8c45fSAndroid Build Coastguard Worker // @START
AParcel_writeInt32(AParcel * parcel,int32_t value)503*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
504*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeInt32(value);
505*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
506*38e8c45fSAndroid Build Coastguard Worker }
507*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeUint32(AParcel * parcel,uint32_t value)508*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
509*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeUint32(value);
510*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
511*38e8c45fSAndroid Build Coastguard Worker }
512*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeInt64(AParcel * parcel,int64_t value)513*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
514*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeInt64(value);
515*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
516*38e8c45fSAndroid Build Coastguard Worker }
517*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeUint64(AParcel * parcel,uint64_t value)518*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
519*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeUint64(value);
520*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
521*38e8c45fSAndroid Build Coastguard Worker }
522*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeFloat(AParcel * parcel,float value)523*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
524*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeFloat(value);
525*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
526*38e8c45fSAndroid Build Coastguard Worker }
527*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeDouble(AParcel * parcel,double value)528*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
529*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeDouble(value);
530*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
531*38e8c45fSAndroid Build Coastguard Worker }
532*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeBool(AParcel * parcel,bool value)533*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
534*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeBool(value);
535*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
536*38e8c45fSAndroid Build Coastguard Worker }
537*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeChar(AParcel * parcel,char16_t value)538*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
539*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeChar(value);
540*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
541*38e8c45fSAndroid Build Coastguard Worker }
542*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeByte(AParcel * parcel,int8_t value)543*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
544*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->writeByte(value);
545*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
546*38e8c45fSAndroid Build Coastguard Worker }
547*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readInt32(const AParcel * parcel,int32_t * value)548*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
549*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readInt32(value);
550*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
551*38e8c45fSAndroid Build Coastguard Worker }
552*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readUint32(const AParcel * parcel,uint32_t * value)553*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
554*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readUint32(value);
555*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
556*38e8c45fSAndroid Build Coastguard Worker }
557*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readInt64(const AParcel * parcel,int64_t * value)558*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
559*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readInt64(value);
560*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
561*38e8c45fSAndroid Build Coastguard Worker }
562*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readUint64(const AParcel * parcel,uint64_t * value)563*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
564*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readUint64(value);
565*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
566*38e8c45fSAndroid Build Coastguard Worker }
567*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readFloat(const AParcel * parcel,float * value)568*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
569*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readFloat(value);
570*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
571*38e8c45fSAndroid Build Coastguard Worker }
572*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readDouble(const AParcel * parcel,double * value)573*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
574*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readDouble(value);
575*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
576*38e8c45fSAndroid Build Coastguard Worker }
577*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readBool(const AParcel * parcel,bool * value)578*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
579*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readBool(value);
580*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
581*38e8c45fSAndroid Build Coastguard Worker }
582*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readChar(const AParcel * parcel,char16_t * value)583*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
584*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readChar(value);
585*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
586*38e8c45fSAndroid Build Coastguard Worker }
587*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readByte(const AParcel * parcel,int8_t * value)588*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
589*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->readByte(value);
590*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
591*38e8c45fSAndroid Build Coastguard Worker }
592*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeInt32Array(AParcel * parcel,const int32_t * arrayData,int32_t length)593*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeInt32Array(AParcel* parcel, const int32_t* arrayData, int32_t length) {
594*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<int32_t>(parcel, arrayData, length);
595*38e8c45fSAndroid Build Coastguard Worker }
596*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeUint32Array(AParcel * parcel,const uint32_t * arrayData,int32_t length)597*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeUint32Array(AParcel* parcel, const uint32_t* arrayData,
598*38e8c45fSAndroid Build Coastguard Worker                                          int32_t length) {
599*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<uint32_t>(parcel, arrayData, length);
600*38e8c45fSAndroid Build Coastguard Worker }
601*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeInt64Array(AParcel * parcel,const int64_t * arrayData,int32_t length)602*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeInt64Array(AParcel* parcel, const int64_t* arrayData, int32_t length) {
603*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<int64_t>(parcel, arrayData, length);
604*38e8c45fSAndroid Build Coastguard Worker }
605*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeUint64Array(AParcel * parcel,const uint64_t * arrayData,int32_t length)606*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeUint64Array(AParcel* parcel, const uint64_t* arrayData,
607*38e8c45fSAndroid Build Coastguard Worker                                          int32_t length) {
608*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<uint64_t>(parcel, arrayData, length);
609*38e8c45fSAndroid Build Coastguard Worker }
610*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeFloatArray(AParcel * parcel,const float * arrayData,int32_t length)611*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeFloatArray(AParcel* parcel, const float* arrayData, int32_t length) {
612*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<float>(parcel, arrayData, length);
613*38e8c45fSAndroid Build Coastguard Worker }
614*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeDoubleArray(AParcel * parcel,const double * arrayData,int32_t length)615*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeDoubleArray(AParcel* parcel, const double* arrayData, int32_t length) {
616*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<double>(parcel, arrayData, length);
617*38e8c45fSAndroid Build Coastguard Worker }
618*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeBoolArray(AParcel * parcel,const void * arrayData,int32_t length,AParcel_boolArrayGetter getter)619*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeBoolArray(AParcel* parcel, const void* arrayData, int32_t length,
620*38e8c45fSAndroid Build Coastguard Worker                                        AParcel_boolArrayGetter getter) {
621*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<bool>(parcel, arrayData, length, getter, &Parcel::writeBool);
622*38e8c45fSAndroid Build Coastguard Worker }
623*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeCharArray(AParcel * parcel,const char16_t * arrayData,int32_t length)624*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeCharArray(AParcel* parcel, const char16_t* arrayData, int32_t length) {
625*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<char16_t>(parcel, arrayData, length);
626*38e8c45fSAndroid Build Coastguard Worker }
627*38e8c45fSAndroid Build Coastguard Worker 
AParcel_writeByteArray(AParcel * parcel,const int8_t * arrayData,int32_t length)628*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_writeByteArray(AParcel* parcel, const int8_t* arrayData, int32_t length) {
629*38e8c45fSAndroid Build Coastguard Worker     return WriteArray<int8_t>(parcel, arrayData, length);
630*38e8c45fSAndroid Build Coastguard Worker }
631*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readInt32Array(const AParcel * parcel,void * arrayData,AParcel_int32ArrayAllocator allocator)632*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readInt32Array(const AParcel* parcel, void* arrayData,
633*38e8c45fSAndroid Build Coastguard Worker                                        AParcel_int32ArrayAllocator allocator) {
634*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<int32_t>(parcel, arrayData, allocator);
635*38e8c45fSAndroid Build Coastguard Worker }
636*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readUint32Array(const AParcel * parcel,void * arrayData,AParcel_uint32ArrayAllocator allocator)637*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readUint32Array(const AParcel* parcel, void* arrayData,
638*38e8c45fSAndroid Build Coastguard Worker                                         AParcel_uint32ArrayAllocator allocator) {
639*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<uint32_t>(parcel, arrayData, allocator);
640*38e8c45fSAndroid Build Coastguard Worker }
641*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readInt64Array(const AParcel * parcel,void * arrayData,AParcel_int64ArrayAllocator allocator)642*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readInt64Array(const AParcel* parcel, void* arrayData,
643*38e8c45fSAndroid Build Coastguard Worker                                        AParcel_int64ArrayAllocator allocator) {
644*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<int64_t>(parcel, arrayData, allocator);
645*38e8c45fSAndroid Build Coastguard Worker }
646*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readUint64Array(const AParcel * parcel,void * arrayData,AParcel_uint64ArrayAllocator allocator)647*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readUint64Array(const AParcel* parcel, void* arrayData,
648*38e8c45fSAndroid Build Coastguard Worker                                         AParcel_uint64ArrayAllocator allocator) {
649*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<uint64_t>(parcel, arrayData, allocator);
650*38e8c45fSAndroid Build Coastguard Worker }
651*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readFloatArray(const AParcel * parcel,void * arrayData,AParcel_floatArrayAllocator allocator)652*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readFloatArray(const AParcel* parcel, void* arrayData,
653*38e8c45fSAndroid Build Coastguard Worker                                        AParcel_floatArrayAllocator allocator) {
654*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<float>(parcel, arrayData, allocator);
655*38e8c45fSAndroid Build Coastguard Worker }
656*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readDoubleArray(const AParcel * parcel,void * arrayData,AParcel_doubleArrayAllocator allocator)657*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readDoubleArray(const AParcel* parcel, void* arrayData,
658*38e8c45fSAndroid Build Coastguard Worker                                         AParcel_doubleArrayAllocator allocator) {
659*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<double>(parcel, arrayData, allocator);
660*38e8c45fSAndroid Build Coastguard Worker }
661*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readBoolArray(const AParcel * parcel,void * arrayData,AParcel_boolArrayAllocator allocator,AParcel_boolArraySetter setter)662*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readBoolArray(const AParcel* parcel, void* arrayData,
663*38e8c45fSAndroid Build Coastguard Worker                                       AParcel_boolArrayAllocator allocator,
664*38e8c45fSAndroid Build Coastguard Worker                                       AParcel_boolArraySetter setter) {
665*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<bool>(parcel, arrayData, allocator, setter, &Parcel::readBool);
666*38e8c45fSAndroid Build Coastguard Worker }
667*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readCharArray(const AParcel * parcel,void * arrayData,AParcel_charArrayAllocator allocator)668*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readCharArray(const AParcel* parcel, void* arrayData,
669*38e8c45fSAndroid Build Coastguard Worker                                       AParcel_charArrayAllocator allocator) {
670*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<char16_t>(parcel, arrayData, allocator);
671*38e8c45fSAndroid Build Coastguard Worker }
672*38e8c45fSAndroid Build Coastguard Worker 
AParcel_readByteArray(const AParcel * parcel,void * arrayData,AParcel_byteArrayAllocator allocator)673*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_readByteArray(const AParcel* parcel, void* arrayData,
674*38e8c45fSAndroid Build Coastguard Worker                                       AParcel_byteArrayAllocator allocator) {
675*38e8c45fSAndroid Build Coastguard Worker     return ReadArray<int8_t>(parcel, arrayData, allocator);
676*38e8c45fSAndroid Build Coastguard Worker }
677*38e8c45fSAndroid Build Coastguard Worker 
AParcel_getAllowFds(const AParcel * parcel)678*38e8c45fSAndroid Build Coastguard Worker bool AParcel_getAllowFds(const AParcel* parcel) {
679*38e8c45fSAndroid Build Coastguard Worker     return parcel->get()->allowFds();
680*38e8c45fSAndroid Build Coastguard Worker }
681*38e8c45fSAndroid Build Coastguard Worker 
AParcel_reset(AParcel * parcel)682*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_reset(AParcel* parcel) {
683*38e8c45fSAndroid Build Coastguard Worker     parcel->get()->freeData();
684*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
685*38e8c45fSAndroid Build Coastguard Worker }
686*38e8c45fSAndroid Build Coastguard Worker 
AParcel_getDataSize(const AParcel * parcel)687*38e8c45fSAndroid Build Coastguard Worker int32_t AParcel_getDataSize(const AParcel* parcel) {
688*38e8c45fSAndroid Build Coastguard Worker     return parcel->get()->dataSize();
689*38e8c45fSAndroid Build Coastguard Worker }
690*38e8c45fSAndroid Build Coastguard Worker 
AParcel_appendFrom(const AParcel * from,AParcel * to,int32_t start,int32_t size)691*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_appendFrom(const AParcel* from, AParcel* to, int32_t start, int32_t size) {
692*38e8c45fSAndroid Build Coastguard Worker     status_t status = to->get()->appendFrom(from->get(), start, size);
693*38e8c45fSAndroid Build Coastguard Worker     return PruneStatusT(status);
694*38e8c45fSAndroid Build Coastguard Worker }
695*38e8c45fSAndroid Build Coastguard Worker 
AParcel_create()696*38e8c45fSAndroid Build Coastguard Worker AParcel* AParcel_create() {
697*38e8c45fSAndroid Build Coastguard Worker     return new AParcel(nullptr);
698*38e8c45fSAndroid Build Coastguard Worker }
699*38e8c45fSAndroid Build Coastguard Worker 
AParcel_marshal(const AParcel * parcel,uint8_t * buffer,size_t start,size_t len)700*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len) {
701*38e8c45fSAndroid Build Coastguard Worker     if (parcel->get()->objectsCount()) {
702*38e8c45fSAndroid Build Coastguard Worker         return STATUS_INVALID_OPERATION;
703*38e8c45fSAndroid Build Coastguard Worker     }
704*38e8c45fSAndroid Build Coastguard Worker     // b/264739302 - getDataSize will return dataPos if it is greater than dataSize
705*38e8c45fSAndroid Build Coastguard Worker     // which will cause crashes in memcpy at later point. Instead compare with
706*38e8c45fSAndroid Build Coastguard Worker     // actual length of internal buffer
707*38e8c45fSAndroid Build Coastguard Worker     int32_t dataSize = parcel->get()->dataBufferSize();
708*38e8c45fSAndroid Build Coastguard Worker     if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
709*38e8c45fSAndroid Build Coastguard Worker         return STATUS_BAD_VALUE;
710*38e8c45fSAndroid Build Coastguard Worker     }
711*38e8c45fSAndroid Build Coastguard Worker     const uint8_t* internalBuffer = parcel->get()->data();
712*38e8c45fSAndroid Build Coastguard Worker     if (internalBuffer == nullptr) {
713*38e8c45fSAndroid Build Coastguard Worker         return STATUS_UNEXPECTED_NULL;
714*38e8c45fSAndroid Build Coastguard Worker     }
715*38e8c45fSAndroid Build Coastguard Worker     memcpy(buffer, internalBuffer + start, len);
716*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
717*38e8c45fSAndroid Build Coastguard Worker }
718*38e8c45fSAndroid Build Coastguard Worker 
AParcel_unmarshal(AParcel * parcel,const uint8_t * buffer,size_t len)719*38e8c45fSAndroid Build Coastguard Worker binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len) {
720*38e8c45fSAndroid Build Coastguard Worker     status_t status = parcel->get()->setDataSize(len);
721*38e8c45fSAndroid Build Coastguard Worker     if (status != ::android::OK) {
722*38e8c45fSAndroid Build Coastguard Worker         return PruneStatusT(status);
723*38e8c45fSAndroid Build Coastguard Worker     }
724*38e8c45fSAndroid Build Coastguard Worker     parcel->get()->setDataPosition(0);
725*38e8c45fSAndroid Build Coastguard Worker 
726*38e8c45fSAndroid Build Coastguard Worker     void* raw = parcel->get()->writeInplace(len);
727*38e8c45fSAndroid Build Coastguard Worker     if (raw == nullptr) {
728*38e8c45fSAndroid Build Coastguard Worker         return STATUS_NO_MEMORY;
729*38e8c45fSAndroid Build Coastguard Worker     }
730*38e8c45fSAndroid Build Coastguard Worker     memcpy(raw, buffer, len);
731*38e8c45fSAndroid Build Coastguard Worker     return STATUS_OK;
732*38e8c45fSAndroid Build Coastguard Worker }
733*38e8c45fSAndroid Build Coastguard Worker 
734*38e8c45fSAndroid Build Coastguard Worker // @END
735