xref: /commonlibrary/c_utils/base/src/parcel.cpp (revision 3f4cbf05)
1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "parcel.h"
17#include "securec.h"
18#include "utils_log.h"
19
20namespace OHOS {
21
22static const size_t DEFAULT_CPACITY = 204800; // 200K
23static const size_t CAPACITY_THRESHOLD = 4096; // 4k
24static const int BINDER_TYPE_HANDLE = 0x73682a85; // binder header type handle
25static const int BINDER_TYPE_FD = 0x66642a85; // binder header type fd
26
27Parcelable::Parcelable() : Parcelable(false)
28{}
29
30Parcelable::Parcelable(bool asRemote)
31{
32    asRemote_ = asRemote;
33    behavior_ = 0;
34}
35
36Parcel::Parcel(Allocator *allocator)
37{
38    if (allocator != nullptr) {
39        allocator_ = allocator;
40    } else {
41        allocator_ = new DefaultAllocator();
42    }
43
44    writeCursor_ = 0;
45    readCursor_ = 0;
46
47    data_ = nullptr;
48    dataSize_ = 0;
49    dataCapacity_ = 0;
50
51    maxDataCapacity_ = DEFAULT_CPACITY;
52    objectOffsets_ = nullptr;
53    nextObjectIdx_ = 0;
54    objectCursor_ = 0;
55    objectsCapacity_ = 0;
56}
57
58Parcel::Parcel() : Parcel(new DefaultAllocator())
59{}
60
61Parcel::~Parcel()
62{
63    FlushBuffer();
64    delete allocator_;
65    allocator_ = nullptr;
66}
67
68size_t Parcel::GetWritableBytes() const
69{
70    if (dataCapacity_ > writeCursor_) {
71        return dataCapacity_ - writeCursor_;
72    }
73
74    return 0;
75}
76
77size_t Parcel::GetReadableBytes() const
78{
79    if (dataSize_ > readCursor_) {
80        return dataSize_ - readCursor_;
81    }
82
83    return 0;
84}
85
86size_t Parcel::CalcNewCapacity(size_t minNewCapacity)
87{
88    size_t threshold = CAPACITY_THRESHOLD;
89
90    if (minNewCapacity == threshold) {
91        return threshold;
92    }
93
94    // If over threshold, step by threshold.
95    if (minNewCapacity > threshold) {
96        size_t newCapacity = minNewCapacity / threshold * threshold;
97
98        if ((maxDataCapacity_ > 0) && (newCapacity > maxDataCapacity_ - threshold)) {
99            newCapacity = maxDataCapacity_;
100        } else {
101            newCapacity += threshold;
102        }
103
104        return newCapacity;
105    }
106
107    // Not over threshold. Double it.
108    size_t newCapacity = 64;
109
110    while (newCapacity < minNewCapacity) {
111        // resize capacity by 2 times
112        newCapacity = newCapacity * 2;
113    }
114
115    if ((maxDataCapacity_ > 0) && (newCapacity > maxDataCapacity_)) {
116        newCapacity = maxDataCapacity_;
117    }
118
119    return newCapacity;
120}
121
122bool Parcel::EnsureWritableCapacity(size_t desireCapacity)
123{
124    if (!writable_) {
125        UTILS_LOGW("this parcel data is alloc by driver, which is can not be writen");
126        return false;
127    }
128    if (desireCapacity <= GetWritableBytes()) {
129        if (data_ == nullptr) {
130            UTILS_LOGE("data_ is nullptr when capacity is available");
131            return false;
132        }
133        return true;
134    }
135
136    size_t minNewCapacity = desireCapacity + writeCursor_;
137    size_t newCapacity = CalcNewCapacity(minNewCapacity);
138    if ((newCapacity <= dataCapacity_) || (newCapacity < minNewCapacity)) {
139        UTILS_LOGW("Failed to ensure parcel capacity, newCapacity = %{public}zu, dataCapacity_ = %{public}zu, "
140                   "minNewCapacity = %{public}zu",
141                   newCapacity, dataCapacity_, minNewCapacity);
142        return false;
143    }
144
145    if (allocator_ != nullptr) {
146        void *newData = allocator_->Realloc(data_, newCapacity);
147        if (newData != nullptr) {
148            data_ = reinterpret_cast<uint8_t *>(newData);
149            dataCapacity_ = newCapacity;
150            return true;
151        }
152        UTILS_LOGW("Failed to realloc parcel capacity, newCapacity = %{public}zu, dataCapacity_ = %{public}zu",
153                   newCapacity, dataCapacity_);
154    }
155
156    return false;
157}
158
159bool Parcel::IsReadObjectData(const size_t nextObj, const size_t upperBound)
160{
161    binder_size_t *objects = objectOffsets_;
162    auto offset = objects[nextObj];
163    auto currentObject = reinterpret_cast<parcel_flat_binder_object *>(data_ + offset);
164    if (currentObject->hdr.type == BINDER_TYPE_FD || currentObject->hdr.type == BINDER_TYPE_HANDLE) {
165        return true;
166    }
167    UTILS_LOGE("Non-object Read object data, readPos = %{public}zu, upperBound = %{public}zu", readCursor_, upperBound);
168    return false;
169}
170
171// ValidateReadData only works in basic type read. It doesn't work when read remote object.
172// And read/write remote object has no effect on "nextObjectIdx_".
173bool Parcel::ValidateReadData([[maybe_unused]]size_t upperBound)
174{
175#ifdef PARCEL_OBJECT_CHECK
176    if (objectOffsets_ == nullptr || objectCursor_ == 0) {
177        return true;
178    }
179    size_t readPos = readCursor_;
180    size_t objSize = objectCursor_;
181    binder_size_t *objects = objectOffsets_;
182    if (nextObjectIdx_ < objSize && upperBound > objects[nextObjectIdx_]) {
183        size_t nextObj = nextObjectIdx_;
184        do {
185            if (readPos < objects[nextObj] + sizeof(parcel_flat_binder_object)) {
186                if (!IsReadObjectData(nextObj, upperBound)) {
187                    return false;
188                }
189            }
190            nextObj++;
191        } while (nextObj < objSize && upperBound > objects[nextObj]);
192        nextObjectIdx_ = nextObj;
193    }
194#endif
195    return true;
196}
197
198size_t Parcel::GetDataSize() const
199{
200    return dataSize_;
201}
202
203uintptr_t Parcel::GetData() const
204{
205    return reinterpret_cast<uintptr_t>(data_);
206}
207
208binder_size_t Parcel::GetObjectOffsets() const
209{
210    return reinterpret_cast<binder_size_t>(objectOffsets_);
211}
212
213size_t Parcel::GetOffsetsSize() const
214{
215    return objectCursor_;
216}
217
218size_t Parcel::GetDataCapacity() const
219{
220    return dataCapacity_;
221}
222
223size_t Parcel::GetMaxCapacity() const
224{
225    return maxDataCapacity_;
226}
227
228bool Parcel::SetMaxCapacity(size_t maxCapacity)
229{
230    if (maxCapacity > maxDataCapacity_) {
231        maxDataCapacity_ = maxCapacity;
232        return true;
233    }
234
235    return false;
236}
237
238bool Parcel::SetAllocator(Allocator *allocator)
239{
240    if ((allocator == nullptr) || (allocator_ == allocator)) {
241        return false;
242    }
243
244    if ((data_ != nullptr) && (dataSize_ > 0)) {
245        if (allocator_ == nullptr) {
246            return false;
247        }
248
249        void *newData = allocator->Alloc(dataSize_);
250        if (newData == nullptr) {
251            UTILS_LOGE("Failed to alloc parcel size, dataSize_ = %{public}zu", dataSize_);
252            return false;
253        }
254
255        if (memcpy_s(newData, dataSize_, data_, dataSize_) != EOK) {
256            allocator->Dealloc(newData);
257            return false;
258        }
259        allocator_->Dealloc(data_);
260        data_ = reinterpret_cast<uint8_t *>(newData);
261        dataCapacity_ = dataSize_;
262    }
263
264    delete allocator_;
265    allocator_ = allocator;
266    return true;
267}
268
269bool Parcel::CheckOffsets()
270{
271    size_t readPos = readCursor_;
272    if ((readPos + sizeof(parcel_flat_binder_object)) > dataSize_) {
273        UTILS_LOGD("CheckOffsets Invalid obj, obj size overflow. objSize:%{public}zu, dataSize:%{public}zu",
274            readPos + sizeof(parcel_flat_binder_object), dataSize_);
275        return false;
276    }
277
278    size_t objSize = objectCursor_;
279    binder_size_t *objects = objectOffsets_;
280    size_t objCount = 0;
281    while (objCount < objSize) {
282        if (objects[objCount] == readPos) {
283            return true;
284        }
285        objCount++;
286    }
287    UTILS_LOGW("CheckOffsets Invalid obj: obj not found.");
288    return false;
289}
290
291void Parcel::InjectOffsets(binder_size_t offsets, size_t offsetSize)
292{
293    if (offsetSize <= 0) {
294        return;
295    }
296
297    auto *newObjectOffsets = reinterpret_cast<binder_size_t *>(offsets);
298    for (size_t index = 0; index < offsetSize; index++) {
299        if (EnsureObjectsCapacity()) {
300            WriteObjectOffset(newObjectOffsets[index]);
301        }
302    }
303}
304
305void Parcel::ClearObjects()
306{
307    objectHolder_.clear();
308    free(objectOffsets_);
309    nextObjectIdx_ = 0;
310    objectCursor_ = 0;
311    objectOffsets_ = nullptr;
312    objectsCapacity_ = 0;
313}
314
315void Parcel::FlushBuffer()
316{
317    if (allocator_ == nullptr) {
318        return;
319    }
320
321    if (data_ != nullptr) {
322        allocator_->Dealloc(data_);
323        dataSize_ = 0;
324        writeCursor_ = 0;
325        readCursor_ = 0;
326        dataCapacity_ = 0;
327        data_ = nullptr;
328    }
329
330    if (objectOffsets_) {
331        ClearObjects();
332    }
333}
334
335bool Parcel::SetDataCapacity(size_t newCapacity)
336{
337    if (allocator_ == nullptr || dataSize_ >= newCapacity) {
338        return false;
339    }
340
341    void *newData = allocator_->Realloc(data_, newCapacity);
342    if (newData != nullptr) {
343        data_ = reinterpret_cast<uint8_t *>(newData);
344        dataCapacity_ = newCapacity;
345        return true;
346    }
347    return false;
348}
349
350bool Parcel::SetDataSize(size_t dataSize)
351{
352    if (dataSize > dataCapacity_) {
353        return false;
354    }
355
356    dataSize_ = dataSize;
357    return true;
358}
359
360bool Parcel::WriteDataBytes(const void *data, size_t size)
361{
362    void *dest = data_ + writeCursor_;
363    size_t writableBytes = GetWritableBytes();
364    if (memcpy_s(dest, writableBytes, data, size) != EOK) {
365        return false;
366    }
367    writeCursor_ += size;
368    dataSize_ += size;
369    return true;
370}
371
372void Parcel::WritePadBytes(size_t padSize)
373{
374    uint8_t *dest = data_ + writeCursor_;
375    static const int MAX_MASK_NUM = 4;
376#if __BYTE_ORDER == __LITTLE_ENDIAN
377    static const size_t mask[MAX_MASK_NUM] = { 0xFFFFFFFF, 0x00ffffff, 0x0000ffff, 0x000000ff };
378#else
379    static const size_t mask[MAX_MASK_NUM] = { 0xFFFFFFFF, 0xffffff00, 0xffff0000, 0xff000000 };
380#endif
381    *reinterpret_cast<uint32_t *>(dest + padSize - MAX_MASK_NUM) &= mask[padSize];
382    writeCursor_ += padSize;
383    dataSize_ += padSize;
384}
385
386bool Parcel::WriteBuffer(const void *data, size_t size)
387{
388    if (data == nullptr || size == 0) {
389        return false;
390    }
391
392    size_t padSize = GetPadSize(size);
393    size_t desireCapacity = size + padSize;
394
395    // in case of desireCapacity overflow
396    if (desireCapacity < size || desireCapacity < padSize) {
397        return false;
398    }
399
400    if (EnsureWritableCapacity(desireCapacity)) {
401        if (!WriteDataBytes(data, size)) {
402            return false;
403        }
404        WritePadBytes(padSize);
405        return true;
406    }
407
408    return false;
409}
410
411bool Parcel::WriteBufferAddTerminator(const void *data, size_t size, size_t typeSize)
412{
413    if (data == nullptr || size < typeSize) {
414        return false;
415    }
416
417    size_t padSize = GetPadSize(size);
418    size_t desireCapacity = size + padSize;
419
420    // in case of desireCapacity overflow
421    if (desireCapacity < size || desireCapacity < padSize) {
422        return false;
423    }
424
425    if (EnsureWritableCapacity(desireCapacity)) {
426        if (!WriteDataBytes(data, size - typeSize)) {
427            return false;
428        }
429
430        // Reserved for 32 bits
431        const char terminator[] = {0, 0, 0, 0};
432        if (!WriteDataBytes(terminator, typeSize)) {
433            return false;
434        }
435        WritePadBytes(padSize);
436        return true;
437    }
438
439    return false;
440}
441
442bool Parcel::WriteUnpadBuffer(const void *data, size_t size)
443{
444    return WriteBuffer(data, size);
445}
446
447template <typename T>
448bool Parcel::Write(T value)
449{
450    size_t desireCapacity = sizeof(T);
451
452    if (EnsureWritableCapacity(desireCapacity)) {
453        *reinterpret_cast<T *>(data_ + writeCursor_) = value;
454        writeCursor_ += desireCapacity;
455        dataSize_ += desireCapacity;
456        return true;
457    }
458
459    return false;
460}
461
462bool Parcel::WriteBool(bool value)
463{
464    return Write<int32_t>(static_cast<int32_t>(value));
465}
466
467bool Parcel::WriteBoolUnaligned(bool value)
468{
469    return Write<bool>(value);
470}
471
472bool Parcel::WriteInt8(int8_t value)
473{
474    return Write<int32_t>(static_cast<int32_t>(value));
475}
476
477bool Parcel::WriteInt8Unaligned(int8_t value)
478{
479    return Write<int8_t>(value);
480}
481
482bool Parcel::WriteInt16(int16_t value)
483{
484    return Write<int32_t>(static_cast<int32_t>(value));
485}
486
487bool Parcel::WriteInt16Unaligned(int16_t value)
488{
489    return Write<int16_t>(value);
490}
491
492bool Parcel::WriteInt32(int32_t value)
493{
494    return Write<int32_t>(value);
495}
496
497bool Parcel::WriteInt64(int64_t value)
498{
499    return Write<int64_t>(value);
500}
501
502bool Parcel::WriteUint8(uint8_t value)
503{
504    return Write<uint32_t>(static_cast<uint32_t>(value));
505}
506
507bool Parcel::WriteUint8Unaligned(uint8_t value)
508{
509    return Write<uint8_t>(value);
510}
511
512bool Parcel::WriteUint16(uint16_t value)
513{
514    return Write<uint32_t>(static_cast<uint32_t>(value));
515}
516
517bool Parcel::WriteUint16Unaligned(uint16_t value)
518{
519    return Write<uint16_t>(value);
520}
521
522bool Parcel::WriteUint32(uint32_t value)
523{
524    return Write<uint32_t>(value);
525}
526
527bool Parcel::WriteUint64(uint64_t value)
528{
529    return Write<uint64_t>(value);
530}
531
532bool Parcel::WriteFloat(float value)
533{
534    return Write<float>(value);
535}
536
537bool Parcel::WriteDouble(double value)
538{
539    return Write<double>(value);
540}
541
542bool Parcel::WritePointer(uintptr_t value)
543{
544    return Write<binder_uintptr_t>(value);
545}
546
547bool Parcel::WriteCString(const char *value)
548{
549    if (value == nullptr) {
550        return false;
551    }
552    int32_t dataLength = strlen(value);
553    if (dataLength < 0 || dataLength >= INT32_MAX) {
554        return false;
555    }
556    int32_t desireCapacity = (dataLength + 1) * sizeof(char);
557    return WriteBuffer(value, desireCapacity);
558}
559
560bool Parcel::WriteString(const std::string &value)
561{
562    if (value.data() == nullptr) {
563        return WriteInt32(-1);
564    }
565
566    int32_t dataLength = value.length();
567    if (dataLength < 0 || dataLength >= INT32_MAX) {
568        return false;
569    }
570    int32_t typeSize = sizeof(char);
571    int32_t desireCapacity = dataLength + typeSize;
572
573    if (!Write<int32_t>(dataLength)) {
574        return false;
575    }
576
577    return WriteBufferAddTerminator(value.data(), desireCapacity, typeSize);
578}
579
580bool Parcel::WriteString16(const std::u16string &value)
581{
582    if (value.data() == nullptr) {
583        return WriteInt32(-1);
584    }
585
586    int32_t dataLength = value.length();
587    int32_t typeSize = sizeof(char16_t);
588    if (dataLength < 0 || dataLength > ((static_cast<int32_t>(INT32_MAX)) / typeSize - 1)) {
589        return false;
590    }
591    int32_t desireCapacity = (dataLength + 1) * typeSize;
592
593    if (!Write<int32_t>(dataLength)) {
594        return false;
595    }
596
597    return WriteBufferAddTerminator(value.data(), desireCapacity, typeSize);
598}
599
600bool Parcel::WriteString16WithLength(const char16_t *value, size_t len)
601{
602    if (!value) {
603        return WriteInt32(-1);
604    }
605
606    int32_t dataLength = len;
607    int32_t typeSize = sizeof(char16_t);
608    if (dataLength < 0 || dataLength > ((static_cast<int32_t>(INT32_MAX)) / typeSize - 1)) {
609        return false;
610    }
611    int32_t desireCapacity = (dataLength + 1) * typeSize;
612    std::u16string u16str(reinterpret_cast<const char16_t *>(value), len);
613
614    if (!Write<int32_t>(dataLength)) {
615        return false;
616    }
617
618    return WriteBufferAddTerminator(u16str.data(), desireCapacity, typeSize);
619}
620
621bool Parcel::WriteString8WithLength(const char *value, size_t len)
622{
623    if (!value) {
624        return WriteInt32(-1);
625    }
626
627    int32_t dataLength = len;
628    if (dataLength < 0 || dataLength >= INT32_MAX) {
629        return false;
630    }
631    int32_t typeSize = sizeof(char);
632    int32_t desireCapacity = (dataLength + 1) * typeSize;
633
634    if (!Write<int32_t>(dataLength)) {
635        return false;
636    }
637
638    return WriteBufferAddTerminator(value, desireCapacity, typeSize);
639}
640
641bool Parcel::EnsureObjectsCapacity()
642{
643    if ((objectsCapacity_ - objectCursor_) >= 1) {
644        return true;
645    }
646
647    if (allocator_ == nullptr) {
648        return false;
649    }
650
651    const int NEW_CAPACITY_ADD = 2;
652    const int NEW_CAPACITY_MULTI = 3;
653    const int NEW_CAPACITY_DIV = 2;
654    size_t newCapacity = ((objectsCapacity_ + NEW_CAPACITY_ADD) * NEW_CAPACITY_MULTI) / NEW_CAPACITY_DIV;
655    size_t newBytes = newCapacity * sizeof(binder_size_t);
656
657    void *newOffsets = realloc(objectOffsets_, newBytes);
658    if (newOffsets == nullptr) {
659        return false;
660    }
661
662    objectOffsets_ = reinterpret_cast<binder_size_t *>(newOffsets);
663    objectsCapacity_ = newCapacity;
664    return true;
665}
666
667const uint8_t *Parcel::ReadBuffer(size_t length, bool isValidate)
668{
669    if (GetReadableBytes() >= length) {
670        uint8_t *buffer = data_ + readCursor_;
671#ifdef PARCEL_OBJECT_CHECK
672        size_t upperBound = readCursor_ + length;
673        if (isValidate && !ValidateReadData(upperBound)) {
674            return nullptr;
675        }
676#endif
677        readCursor_ += length;
678        return buffer;
679    }
680
681    return nullptr;
682}
683
684bool Parcel::WriteObjectOffset(binder_size_t offset)
685{
686    if (offset > dataSize_) {
687        return false;
688    }
689
690    for (size_t index = 0; index < objectCursor_; index++) {
691        if (objectOffsets_[index] == offset) {
692            return false;
693        }
694    }
695
696    objectOffsets_[objectCursor_] = offset;
697    objectCursor_++;
698    return true;
699}
700
701bool Parcel::WriteRemoteObject(const Parcelable *object)
702{
703    size_t placeholder = writeCursor_;
704    // Parcelable is nullptr
705    if ((object == nullptr) || (!object->asRemote_)) {
706        return false;
707    }
708
709    if (!EnsureObjectsCapacity()) {
710        return false;
711    }
712
713    if (!object->Marshalling(*this)) {
714        return false;
715    }
716
717    WriteObjectOffset(placeholder);
718
719    if (object->TestBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT)) {
720        sptr<Parcelable> tmp(const_cast<Parcelable *>(object));
721        objectHolder_.push_back(tmp);
722    }
723
724    return true;
725}
726
727bool Parcel::WriteParcelable(const Parcelable *object)
728{
729    size_t placeholder = writeCursor_;
730    size_t restorSize = dataSize_;
731
732    // Parcelable is nullptr
733    if (object == nullptr) {
734        // write the meta data to indicate pass an null object.
735        return WriteInt32(0);
736    }
737
738    if (!object->asRemote_) {
739        // meta data indicate we have an parcelable object.
740        if (!WriteInt32(1)) {
741            return false;
742        }
743
744        return object->Marshalling(*this);
745    }
746
747    // Write the remote object flag
748    if (!WriteInt32(1)) {
749        return false;
750    }
751
752    if (WriteRemoteObject(const_cast<Parcelable*>(object))) {
753        return true;
754    }
755
756    // rollback the write position.
757    writeCursor_ = placeholder;
758    dataSize_ = restorSize;
759    return false;
760}
761
762bool Parcel::WriteStrongParcelable(const sptr<Parcelable> &object)
763{
764    if (object == nullptr) {
765        WriteInt32(0);
766        return true;
767    }
768
769    object->SetBehavior(Parcelable::BehaviorFlag::HOLD_OBJECT);
770    return WriteParcelable(object.GetRefPtr());
771}
772
773template <typename T>
774bool Parcel::Read(T &value)
775{
776    size_t desireCapacity = sizeof(T);
777
778    if (desireCapacity <= GetReadableBytes()) {
779        const void *data = data_ + readCursor_;
780#ifdef PARCEL_OBJECT_CHECK
781        size_t upperBound = readCursor_ + desireCapacity;
782        if (!ValidateReadData(upperBound)) {
783            readCursor_ += desireCapacity;
784            return false;
785        }
786#endif
787        readCursor_ += desireCapacity;
788        value = *reinterpret_cast<const T *>(data);
789        return true;
790    }
791
792    return false;
793}
794
795template <typename T>
796T Parcel::Read()
797{
798    T lvalue {};
799    return Read<T>(lvalue) ? lvalue : 0;
800}
801
802bool Parcel::ParseFrom(uintptr_t data, size_t size)
803{
804    if (data_ != nullptr) {
805        return false;
806    }
807
808    data_ = reinterpret_cast<uint8_t *>(data);
809    dataCapacity_ = size;
810    dataSize_ = size;
811    /* data is alloc by driver, can not write again */
812    writable_ = false;
813#ifdef PARCEL_OBJECT_CHECK
814    if (objectOffsets_) {
815        ClearObjects();
816    }
817#endif
818    return true;
819}
820
821const uint8_t *Parcel::ReadBuffer(size_t length)
822{
823    if (GetReadableBytes() >= length) {
824        uint8_t *buffer = data_ + readCursor_;
825#ifdef PARCEL_OBJECT_CHECK
826        size_t upperBound = readCursor_ + length;
827        if (!ValidateReadData(upperBound)) {
828            return nullptr;
829        }
830#endif
831        readCursor_ += length;
832        return buffer;
833    }
834
835    return nullptr;
836}
837
838const uint8_t *Parcel::BasicReadBuffer([[maybe_unused]]size_t length)
839{
840#ifdef PARCEL_OBJECT_CHECK
841    if (GetReadableBytes() >= length) {
842        uint8_t *buffer = data_ + readCursor_;
843        size_t upperBound = readCursor_ + length;
844        if (!ValidateReadData(upperBound)) {
845            readCursor_ += length;
846            return nullptr;
847        }
848        readCursor_ += length;
849        return buffer;
850    }
851#endif
852    return nullptr;
853}
854
855const uint8_t *Parcel::ReadUnpadBuffer(size_t length)
856{
857    if (GetReadableBytes() >= length) {
858        uint8_t *buffer = data_ + readCursor_;
859#ifdef PARCEL_OBJECT_CHECK
860        size_t upperBound = readCursor_ + length;
861        if (!ValidateReadData(upperBound)) {
862            return nullptr;
863        }
864#endif
865        readCursor_ += length;
866        SkipBytes(GetPadSize(length));
867        return buffer;
868    }
869
870    return nullptr;
871}
872
873void Parcel::SkipBytes(size_t bytes)
874{
875    if (GetReadableBytes() >= bytes) {
876        readCursor_ += bytes;
877    } else if (readCursor_ < dataCapacity_) {
878        readCursor_ = dataCapacity_;
879    }
880}
881
882size_t Parcel::GetReadPosition()
883{
884    return readCursor_;
885}
886
887bool Parcel::RewindRead(size_t newPosition)
888{
889    if (newPosition > dataSize_) {
890        return false;
891    }
892    readCursor_ = newPosition;
893    nextObjectIdx_ = 0;
894    return true;
895}
896
897size_t Parcel::GetWritePosition()
898{
899    return writeCursor_;
900}
901
902bool Parcel::RewindWrite(size_t newPosition)
903{
904    if (newPosition > dataSize_) {
905        return false;
906    }
907    writeCursor_ = newPosition;
908    dataSize_ = newPosition;
909#ifdef PARCEL_OBJECT_CHECK
910    if (objectOffsets_ == nullptr || objectCursor_ == 0) {
911        return true;
912    }
913    size_t objectSize = objectCursor_;
914    if (objectOffsets_[objectSize - 1] + sizeof(parcel_flat_binder_object) > newPosition) {
915        while (objectSize > 0) {
916            if (objectOffsets_[objectSize - 1] + sizeof(parcel_flat_binder_object) <= newPosition) {
917                break;
918            }
919            objectSize--;
920        }
921        if (objectSize == 0) {
922            ClearObjects();
923            return true;
924        }
925        size_t newBytes = objectSize * sizeof(binder_size_t);
926        void *newOffsets = realloc(objectOffsets_, newBytes);
927        if (newOffsets == nullptr) {
928            return false;
929        }
930        objectOffsets_ = reinterpret_cast<binder_size_t *>(newOffsets);
931        objectCursor_ = objectSize;
932        objectsCapacity_ = objectCursor_;
933        objectHolder_.resize(objectSize);
934        nextObjectIdx_ = 0;
935        return true;
936    }
937#endif
938    return true;
939}
940
941bool Parcel::ReadBool()
942{
943    int32_t temp = Read<int32_t>();
944    return (temp != 0);
945}
946
947bool Parcel::ReadBoolUnaligned()
948{
949    return Read<bool>();
950}
951
952int8_t Parcel::ReadInt8()
953{
954    int32_t temp = Read<int32_t>();
955    return static_cast<int8_t>(temp);
956}
957
958int16_t Parcel::ReadInt16()
959{
960    int32_t temp = Read<int32_t>();
961    return static_cast<int16_t>(temp);
962}
963
964int32_t Parcel::ReadInt32()
965{
966    return Read<int32_t>();
967}
968
969int64_t Parcel::ReadInt64()
970{
971    return Read<int64_t>();
972}
973
974uint8_t Parcel::ReadUint8()
975{
976    uint32_t temp = Read<uint32_t>();
977    return static_cast<uint8_t>(temp);
978}
979
980uint16_t Parcel::ReadUint16()
981{
982    uint32_t temp = Read<uint32_t>();
983    return static_cast<uint16_t>(temp);
984}
985
986uint32_t Parcel::ReadUint32()
987{
988    return Read<uint32_t>();
989}
990
991uint64_t Parcel::ReadUint64()
992{
993    return Read<uint64_t>();
994}
995
996float Parcel::ReadFloat()
997{
998    return Read<float>();
999}
1000
1001double Parcel::ReadDouble()
1002{
1003    return Read<double>();
1004}
1005
1006template <typename T>
1007bool Parcel::ReadPadded(T &value)
1008{
1009    int32_t temp;
1010    bool result = Read<int32_t>(temp);
1011    if (result) {
1012        value = static_cast<T>(temp);
1013    }
1014
1015    return result;
1016}
1017
1018bool Parcel::ReadBool(bool &value)
1019{
1020    return ReadPadded<bool>(value);
1021}
1022
1023bool Parcel::ReadInt8(int8_t &value)
1024{
1025    return ReadPadded<int8_t>(value);
1026}
1027
1028bool Parcel::ReadInt8Unaligned(int8_t &value)
1029{
1030    return Read<int8_t>(value);
1031}
1032
1033bool Parcel::ReadInt16(int16_t &value)
1034{
1035    return ReadPadded<int16_t>(value);
1036}
1037
1038bool Parcel::ReadInt16Unaligned(int16_t &value)
1039{
1040    return Read<int16_t>(value);
1041}
1042
1043bool Parcel::ReadInt32(int32_t &value)
1044{
1045    return Read<int32_t>(value);
1046}
1047
1048bool Parcel::ReadInt64(int64_t &value)
1049{
1050    return Read<int64_t>(value);
1051}
1052
1053bool Parcel::ReadUint8(uint8_t &value)
1054{
1055    return ReadPadded<uint8_t>(value);
1056}
1057
1058bool Parcel::ReadUint8Unaligned(uint8_t &value)
1059{
1060    return Read<uint8_t>(value);
1061}
1062
1063bool Parcel::ReadUint16(uint16_t &value)
1064{
1065    return ReadPadded<uint16_t>(value);
1066}
1067
1068bool Parcel::ReadUint16Unaligned(uint16_t &value)
1069{
1070    return Read<uint16_t>(value);
1071}
1072
1073bool Parcel::ReadUint32(uint32_t &value)
1074{
1075    return Read<uint32_t>(value);
1076}
1077
1078bool Parcel::ReadUint64(uint64_t &value)
1079{
1080    return Read<uint64_t>(value);
1081}
1082
1083bool Parcel::ReadFloat(float &value)
1084{
1085    return Read<float>(value);
1086}
1087
1088bool Parcel::ReadDouble(double &value)
1089{
1090    return Read<double>(value);
1091}
1092
1093uintptr_t Parcel::ReadPointer()
1094{
1095    return Read<binder_uintptr_t>();
1096}
1097
1098const char *Parcel::ReadCString()
1099{
1100    size_t oldCursor = readCursor_;
1101    const size_t avail = GetReadableBytes();
1102    const char* cstr = reinterpret_cast<const char*>(data_ + readCursor_);
1103    // is the string's trailing NUL within the parcel's valid bounds?
1104    const char* eos = reinterpret_cast<const char*>(memchr(cstr, 0, avail));
1105    if (eos != nullptr) {
1106        const size_t dataLength = eos - cstr;
1107        readCursor_ += (dataLength + 1);
1108        SkipBytes(GetPadSize(dataLength + 1));
1109        return cstr;
1110    }
1111    readCursor_ = oldCursor;
1112    return nullptr;
1113}
1114
1115const std::string Parcel::ReadString()
1116{
1117    int32_t dataLength = 0;
1118    size_t oldCursor = readCursor_;
1119
1120    if (!Read<int32_t>(dataLength) || dataLength < 0 || dataLength >= INT32_MAX) {
1121        return std::string();
1122    }
1123
1124    size_t readCapacity = static_cast<size_t>(dataLength) + 1;
1125    if (readCapacity <= GetReadableBytes()) {
1126#ifdef PARCEL_OBJECT_CHECK
1127        const uint8_t *dest = BasicReadBuffer(readCapacity);
1128#else
1129        const uint8_t *dest = ReadBuffer(readCapacity);
1130#endif
1131        if (dest != nullptr) {
1132            const auto *str = reinterpret_cast<const char *>(dest);
1133            SkipBytes(GetPadSize(readCapacity));
1134            if (str[dataLength] == 0) {
1135                return std::string(str, dataLength);
1136            }
1137        }
1138    }
1139
1140    readCursor_ = oldCursor;
1141    return std::string();
1142}
1143
1144bool Parcel::ReadString(std::string &value)
1145{
1146    int32_t dataLength = 0;
1147    size_t oldCursor = readCursor_;
1148
1149    if (!Read<int32_t>(dataLength) || dataLength < 0 || dataLength >= INT32_MAX) {
1150        value = std::string();
1151        return false;
1152    }
1153
1154    size_t readCapacity = static_cast<size_t>(dataLength) + 1;
1155    if (readCapacity <= GetReadableBytes()) {
1156#ifdef PARCEL_OBJECT_CHECK
1157        const uint8_t *dest = BasicReadBuffer(readCapacity);
1158#else
1159        const uint8_t *dest = ReadBuffer(readCapacity);
1160#endif
1161        if (dest != nullptr) {
1162            const auto *str = reinterpret_cast<const char *>(dest);
1163            SkipBytes(GetPadSize(readCapacity));
1164            if (str[dataLength] == 0) {
1165                value = std::string(str, dataLength);
1166                return true;
1167            }
1168        }
1169    }
1170
1171    readCursor_ = oldCursor;
1172    value = std::string();
1173    return false;
1174}
1175
1176const std::u16string Parcel::ReadString16()
1177{
1178    int32_t dataLength = 0;
1179    size_t oldCursor = readCursor_;
1180
1181    if (!Read<int32_t>(dataLength) || dataLength < 0 || dataLength >= INT32_MAX) {
1182        return std::u16string();
1183    }
1184
1185    size_t readCapacity = (static_cast<size_t>(dataLength) + 1) * sizeof(char16_t);
1186    if ((readCapacity > (static_cast<size_t>(dataLength))) && (readCapacity <= GetReadableBytes())) {
1187#ifdef PARCEL_OBJECT_CHECK
1188        const uint8_t *str = BasicReadBuffer(readCapacity);
1189#else
1190        const uint8_t *str = ReadBuffer(readCapacity);
1191#endif
1192        if (str != nullptr) {
1193            const auto *u16Str = reinterpret_cast<const char16_t *>(str);
1194            SkipBytes(GetPadSize(readCapacity));
1195            if (u16Str[dataLength] == 0) {
1196                return std::u16string(u16Str, dataLength);
1197            }
1198        }
1199    }
1200
1201    readCursor_ = oldCursor;
1202    return std::u16string();
1203}
1204
1205bool Parcel::ReadString16(std::u16string &value)
1206{
1207    int32_t dataLength = 0;
1208    size_t oldCursor = readCursor_;
1209
1210    if (!Read<int32_t>(dataLength) || dataLength < 0 || dataLength >= INT32_MAX) {
1211        value = std::u16string();
1212        return false;
1213    }
1214
1215    size_t readCapacity = (static_cast<size_t>(dataLength) + 1) * sizeof(char16_t);
1216    if ((readCapacity > (static_cast<size_t>(dataLength))) && (readCapacity <= GetReadableBytes())) {
1217#ifdef PARCEL_OBJECT_CHECK
1218        const uint8_t *str = BasicReadBuffer(readCapacity);
1219#else
1220        const uint8_t *str = ReadBuffer(readCapacity);
1221#endif
1222        if (str != nullptr) {
1223            const auto *u16Str = reinterpret_cast<const char16_t *>(str);
1224            SkipBytes(GetPadSize(readCapacity));
1225            if (u16Str[dataLength] == 0) {
1226                value = std::u16string(u16Str, dataLength);
1227                return true;
1228            }
1229        }
1230    }
1231
1232    readCursor_ = oldCursor;
1233    value = std::u16string();
1234    return false;
1235}
1236
1237const std::u16string Parcel::ReadString16WithLength(int32_t &readLength)
1238{
1239    int32_t dataLength = 0;
1240    size_t oldCursor = readCursor_;
1241
1242    if (!Read<int32_t>(dataLength)) {
1243        return std::u16string();
1244    }
1245
1246    if (dataLength < 0 || dataLength >= INT32_MAX) {
1247        readLength = dataLength;
1248        return std::u16string();
1249    }
1250
1251    size_t readCapacity = (static_cast<size_t>(dataLength) + 1) * sizeof(char16_t);
1252    if ((readCapacity > (static_cast<size_t>(dataLength))) && (readCapacity <= GetReadableBytes())) {
1253#ifdef PARCEL_OBJECT_CHECK
1254        const uint8_t *str = BasicReadBuffer(readCapacity);
1255#else
1256        const uint8_t *str = ReadBuffer(readCapacity);
1257#endif
1258        if (str != nullptr) {
1259            const auto *u16Str = reinterpret_cast<const char16_t *>(str);
1260            SkipBytes(GetPadSize(readCapacity));
1261            if (u16Str[dataLength] == 0) {
1262                readLength = dataLength;
1263                return std::u16string(u16Str, dataLength);
1264            }
1265        }
1266    }
1267
1268    readCursor_ = oldCursor;
1269    return std::u16string();
1270}
1271
1272const std::string Parcel::ReadString8WithLength(int32_t &readLength)
1273{
1274    int32_t dataLength = 0;
1275    size_t oldCursor = readCursor_;
1276
1277    if (!Read<int32_t>(dataLength)) {
1278        return std::string();
1279    }
1280
1281    if (dataLength < 0 || dataLength >= INT32_MAX) {
1282        readLength = dataLength;
1283        return std::string();
1284    }
1285
1286    size_t readCapacity = (static_cast<size_t>(dataLength) + 1) * sizeof(char);
1287    if (readCapacity <= GetReadableBytes()) {
1288#ifdef PARCEL_OBJECT_CHECK
1289        const uint8_t *str = BasicReadBuffer(readCapacity);
1290#else
1291        const uint8_t *str = ReadBuffer(readCapacity);
1292#endif
1293        if (str != nullptr) {
1294            const auto *u8Str = reinterpret_cast<const char *>(str);
1295            SkipBytes(GetPadSize(readCapacity));
1296            if (u8Str[dataLength] == 0) {
1297                readLength = dataLength;
1298                return std::string(u8Str, dataLength);
1299            }
1300        }
1301    }
1302
1303    readCursor_ = oldCursor;
1304    return std::string();
1305}
1306
1307void *DefaultAllocator::Alloc(size_t size)
1308{
1309    return malloc(size);
1310}
1311
1312void DefaultAllocator::Dealloc(void *data)
1313{
1314    if (data != nullptr) {
1315        free(data);
1316    }
1317}
1318
1319void *DefaultAllocator::Realloc(void *data, size_t newSize)
1320{
1321    return realloc(data, newSize);
1322}
1323
1324template <typename T1, typename T2>
1325bool Parcel::WriteVector(const std::vector<T1> &val, bool (Parcel::*Write)(T2))
1326{
1327    if (val.size() > INT_MAX) {
1328        return false;
1329    }
1330
1331    if (!this->WriteInt32(static_cast<int32_t>(val.size()))) {
1332        return false;
1333    }
1334
1335    for (const auto &v : val) {
1336        if (!(this->*Write)(v)) {
1337            return false;
1338        }
1339    }
1340
1341    size_t padSize = this->GetPadSize(val.size() * sizeof(T1));
1342    if (!EnsureWritableCapacity(padSize)) {
1343        return false;
1344    }
1345    this->WritePadBytes(padSize);
1346    return true;
1347}
1348
1349template <typename Type, typename T1, typename T2>
1350bool Parcel::WriteFixedAlignVector(const std::vector<T1> &originVal, bool (Parcel::*SpecialWrite)(T2))
1351{
1352    if (originVal.size() > INT_MAX) {
1353        return false;
1354    }
1355
1356    if (!this->WriteInt32(static_cast<int32_t>(originVal.size()))) {
1357        return false;
1358    }
1359    // Use the specified interface to write a single element.
1360    for (const auto &v : originVal) {
1361        if (!(this->*SpecialWrite)(v)) {
1362            return false;
1363        }
1364    }
1365    // The write length of these interfaces is different from the original type.
1366    // They need to use the specified write length and calculate the padSize based on this.
1367    size_t padSize = this->GetPadSize(originVal.size() * sizeof(Type));
1368    if (!EnsureWritableCapacity(padSize)) {
1369        return false;
1370    }
1371    this->WritePadBytes(padSize);
1372    return true;
1373}
1374
1375bool Parcel::WriteBoolVector(const std::vector<bool> &val)
1376{
1377    return WriteFixedAlignVector<int32_t>(val, &Parcel::WriteBool);
1378}
1379
1380bool Parcel::WriteInt8Vector(const std::vector<int8_t> &val)
1381{
1382    return WriteVector(val, &Parcel::WriteInt8Unaligned);
1383}
1384
1385bool Parcel::WriteInt16Vector(const std::vector<int16_t> &val)
1386{
1387    return WriteFixedAlignVector<int32_t>(val, &Parcel::WriteInt16);
1388}
1389
1390bool Parcel::WriteInt32Vector(const std::vector<int32_t> &val)
1391{
1392    return WriteVector(val, &Parcel::WriteInt32);
1393}
1394
1395bool Parcel::WriteInt64Vector(const std::vector<int64_t> &val)
1396{
1397    return WriteVector(val, &Parcel::WriteInt64);
1398}
1399
1400bool Parcel::WriteUInt8Vector(const std::vector<uint8_t> &val)
1401{
1402    return WriteVector(val, &Parcel::WriteUint8Unaligned);
1403}
1404
1405bool Parcel::WriteUInt16Vector(const std::vector<uint16_t> &val)
1406{
1407    return WriteVector(val, &Parcel::WriteUint16Unaligned);
1408}
1409
1410bool Parcel::WriteUInt32Vector(const std::vector<uint32_t> &val)
1411{
1412    return WriteVector(val, &Parcel::WriteUint32);
1413}
1414
1415bool Parcel::WriteUInt64Vector(const std::vector<uint64_t> &val)
1416{
1417    return WriteVector(val, &Parcel::WriteUint64);
1418}
1419
1420bool Parcel::WriteFloatVector(const std::vector<float> &val)
1421{
1422    return WriteVector(val, &Parcel::WriteFloat);
1423}
1424
1425bool Parcel::WriteDoubleVector(const std::vector<double> &val)
1426{
1427    return WriteVector(val, &Parcel::WriteDouble);
1428}
1429
1430bool Parcel::WriteStringVector(const std::vector<std::string> &val)
1431{
1432    return WriteVector(val, &Parcel::WriteString);
1433}
1434
1435bool Parcel::WriteString16Vector(const std::vector<std::u16string> &val)
1436{
1437    return WriteVector(val, &Parcel::WriteString16);
1438}
1439
1440template <typename T>
1441bool Parcel::ReadVector(std::vector<T> *val, bool (Parcel::*Read)(T &))
1442{
1443    if (val == nullptr) {
1444        return false;
1445    }
1446
1447    int32_t len = this->ReadInt32();
1448    if (len < 0) {
1449        return false;
1450    }
1451
1452    size_t readAbleSize = this->GetReadableBytes() / sizeof(T);
1453    size_t size = static_cast<size_t>(len);
1454    if ((size > readAbleSize) || (size > val->max_size())) {
1455        UTILS_LOGE("Failed to read vector, size = %{public}zu, readAbleSize = %{public}zu", size, readAbleSize);
1456        return false;
1457    }
1458    val->resize(size);
1459    if (val->size() < size) {
1460        return false;
1461    }
1462
1463    for (auto &v : *val) {
1464        if (!(this->*Read)(v)) {
1465            return false;
1466        }
1467    }
1468
1469    size_t padSize = this->GetPadSize(size * sizeof(T));
1470    this->SkipBytes(padSize);
1471    return true;
1472}
1473
1474template <typename Type, typename T1, typename T2>
1475bool Parcel::ReadFixedAlignVector(std::vector<T1> *val, bool (Parcel::*SpecialRead)(T2 &))
1476{
1477    if (val == nullptr) {
1478        return false;
1479    }
1480
1481    int32_t len = this->ReadInt32();
1482    if (len < 0) {
1483        return false;
1484    }
1485
1486    size_t readAbleSize = this->GetReadableBytes() / sizeof(Type);
1487    size_t size = static_cast<size_t>(len);
1488    if ((size > readAbleSize) || (size > val->max_size())) {
1489        UTILS_LOGE("Failed to fixed aligned read vector, size = %{public}zu, readAbleSize = %{public}zu",
1490            size, readAbleSize);
1491        return false;
1492    }
1493    val->resize(size);
1494    if (val->size() < size) {
1495        return false;
1496    }
1497
1498    for (size_t i = 0; i < size; ++i) {
1499        T2 parcelVal;
1500        if (!(this->*SpecialRead)(parcelVal)) {
1501            return false;
1502        }
1503        (*val)[i] = parcelVal;
1504    }
1505
1506    size_t padSize = this->GetPadSize(size * sizeof(Type));
1507    this->SkipBytes(padSize);
1508    return true;
1509}
1510
1511bool Parcel::ReadBoolVector(std::vector<bool> *val)
1512{
1513    return ReadFixedAlignVector<int32_t>(val, &Parcel::ReadBool);
1514}
1515
1516bool Parcel::ReadInt8Vector(std::vector<int8_t> *val)
1517{
1518    return ReadVector(val, &Parcel::ReadInt8Unaligned);
1519}
1520
1521bool Parcel::ReadInt16Vector(std::vector<int16_t> *val)
1522{
1523    return ReadFixedAlignVector<int32_t>(val, &Parcel::ReadInt16);
1524}
1525
1526bool Parcel::ReadInt32Vector(std::vector<int32_t> *val)
1527{
1528    return ReadVector(val, &Parcel::ReadInt32);
1529}
1530
1531bool Parcel::ReadInt64Vector(std::vector<int64_t> *val)
1532{
1533    return ReadVector(val, &Parcel::ReadInt64);
1534}
1535
1536bool Parcel::ReadUInt8Vector(std::vector<uint8_t> *val)
1537{
1538    return ReadVector(val, &Parcel::ReadUint8Unaligned);
1539}
1540
1541bool Parcel::ReadUInt16Vector(std::vector<uint16_t> *val)
1542{
1543    return ReadVector(val, &Parcel::ReadUint16Unaligned);
1544}
1545
1546bool Parcel::ReadUInt32Vector(std::vector<uint32_t> *val)
1547{
1548    return ReadVector(val, &Parcel::ReadUint32);
1549}
1550
1551bool Parcel::ReadUInt64Vector(std::vector<uint64_t> *val)
1552{
1553    return ReadVector(val, &Parcel::ReadUint64);
1554}
1555
1556bool Parcel::ReadFloatVector(std::vector<float> *val)
1557{
1558    return ReadVector(val, &Parcel::ReadFloat);
1559}
1560
1561bool Parcel::ReadDoubleVector(std::vector<double> *val)
1562{
1563    return ReadVector(val, &Parcel::ReadDouble);
1564}
1565
1566bool Parcel::ReadStringVector(std::vector<std::string> *val)
1567{
1568    if (val == nullptr) {
1569        return false;
1570    }
1571
1572    int32_t len = this->ReadInt32();
1573    if (len < 0) {
1574        return false;
1575    }
1576
1577    size_t readAbleSize = this->GetReadableBytes();
1578    size_t size = static_cast<size_t>(len);
1579    if ((size > readAbleSize) || (val->max_size() < size)) {
1580        UTILS_LOGE("Failed to read string vector, size = %{public}zu, readAbleSize = %{public}zu", size, readAbleSize);
1581        return false;
1582    }
1583    val->resize(size);
1584    if (val->size() < size) {
1585        return false;
1586    }
1587
1588    for (auto &v : *val) {
1589        v = ReadString();
1590    }
1591
1592    return true;
1593}
1594
1595bool Parcel::ReadString16Vector(std::vector<std::u16string> *val)
1596{
1597    if (val == nullptr) {
1598        return false;
1599    }
1600
1601    int32_t len = this->ReadInt32();
1602    if (len < 0) {
1603        return false;
1604    }
1605
1606    size_t readAbleSize = this->GetReadableBytes();
1607    size_t size = static_cast<size_t>(len);
1608    if ((size > readAbleSize) || (val->max_size() < size)) {
1609        UTILS_LOGE("Failed to read u16string vector, size = %{public}zu, readAbleSize = %{public}zu",
1610            size, readAbleSize);
1611        return false;
1612    }
1613
1614    val->resize(size);
1615    if (val->size() < size) {
1616        return false;
1617    }
1618
1619    for (auto &v : *val) {
1620        v = ReadString16();
1621    }
1622
1623    return true;
1624}
1625}  // namespace OHOS
1626