• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <binder/Parcel.h>
18 #include <binder/Parcelable.h>
19 #include <binder/ParcelableHolder.h>
20 
21 #define RETURN_ON_FAILURE(expr)                     \
22     do {                                            \
23         android::status_t _status = (expr);         \
24         if (_status != android::OK) return _status; \
25     } while (false)
26 
27 namespace android {
28 namespace os {
writeToParcel(Parcel * p) const29 status_t ParcelableHolder::writeToParcel(Parcel* p) const {
30     RETURN_ON_FAILURE(p->writeInt32(static_cast<int32_t>(this->getStability())));
31     if (this->mParcelPtr) {
32         RETURN_ON_FAILURE(p->writeInt32(this->mParcelPtr->dataSize()));
33         RETURN_ON_FAILURE(p->appendFrom(this->mParcelPtr.get(), 0, this->mParcelPtr->dataSize()));
34         return OK;
35     }
36     if (this->mParcelable) {
37         size_t sizePos = p->dataPosition();
38         RETURN_ON_FAILURE(p->writeInt32(0));
39         size_t dataStartPos = p->dataPosition();
40         RETURN_ON_FAILURE(p->writeString16(this->mParcelableName));
41         this->mParcelable->writeToParcel(p);
42         size_t dataSize = p->dataPosition() - dataStartPos;
43 
44         p->setDataPosition(sizePos);
45         RETURN_ON_FAILURE(p->writeInt32(dataSize));
46         p->setDataPosition(p->dataPosition() + dataSize);
47         return OK;
48     }
49 
50     RETURN_ON_FAILURE(p->writeInt32(0));
51     return OK;
52 }
53 
readFromParcel(const Parcel * p)54 status_t ParcelableHolder::readFromParcel(const Parcel* p) {
55     int32_t wireStability;
56     if (status_t status = p->readInt32(&wireStability); status != OK) return status;
57     if (static_cast<int32_t>(this->mStability) != wireStability) return BAD_VALUE;
58 
59     this->mParcelable = nullptr;
60     this->mParcelableName = std::nullopt;
61     int32_t rawDataSize;
62 
63     status_t status = p->readInt32(&rawDataSize);
64     if (status != android::OK || rawDataSize < 0) {
65         this->mParcelPtr = nullptr;
66         return status != android::OK ? status : BAD_VALUE;
67     }
68     if (rawDataSize == 0) {
69         if (this->mParcelPtr) {
70             this->mParcelPtr = nullptr;
71         }
72         return OK;
73     }
74 
75     size_t dataSize = rawDataSize;
76 
77     size_t dataStartPos = p->dataPosition();
78 
79     if (dataStartPos > SIZE_MAX - dataSize) {
80         this->mParcelPtr = nullptr;
81         return BAD_VALUE;
82     }
83 
84     if (!this->mParcelPtr) {
85         this->mParcelPtr = std::make_unique<Parcel>();
86     }
87     this->mParcelPtr->freeData();
88 
89     status = this->mParcelPtr->appendFrom(p, dataStartPos, dataSize);
90     if (status != android::OK) {
91         this->mParcelPtr = nullptr;
92         return status;
93     }
94     p->setDataPosition(dataStartPos + dataSize);
95     return OK;
96 }
97 } // namespace os
98 } // namespace android
99