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 "common/hap_byte_buffer.h"
17 
18 #include "common/hap_verify_log.h"
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace Security {
23 namespace Verify {
24 const int32_t HapByteBuffer::MAX_PRINT_LENGTH = 200;
25 const int32_t HapByteBuffer::HEX_PRINT_LENGTH = 3;
26 
HapByteBuffer()27 HapByteBuffer::HapByteBuffer() : buffer(nullptr), position(0), limit(0), capacity(0)
28 {
29 }
30 
HapByteBuffer(int32_t bufferCapacity)31 HapByteBuffer::HapByteBuffer(int32_t bufferCapacity) : buffer(nullptr), position(0), limit(0), capacity(0)
32 {
33     Init(bufferCapacity);
34 }
35 
HapByteBuffer(const HapByteBuffer & other)36 HapByteBuffer::HapByteBuffer(const HapByteBuffer& other) : buffer(nullptr), position(0), limit(0), capacity(0)
37 {
38     Init(other.GetCapacity());
39     if (buffer != nullptr && capacity > 0) {
40         if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
41             HAPVERIFY_LOG_ERROR("memcpy_s failed");
42             return;
43         }
44         position = other.GetPosition();
45         limit = other.GetLimit();
46     }
47 }
48 
~HapByteBuffer()49 HapByteBuffer::~HapByteBuffer()
50 {
51     buffer.reset(nullptr);
52 }
53 
Init(int32_t bufferCapacity)54 void HapByteBuffer::Init(int32_t bufferCapacity)
55 {
56     if (bufferCapacity > 0) {
57         buffer = std::make_unique<char[]>(bufferCapacity);
58         if (buffer != nullptr) {
59             limit = bufferCapacity;
60             capacity = bufferCapacity;
61         }
62     } else {
63         HAPVERIFY_LOG_INFO("bufferCapacity %{public}d is too small", bufferCapacity);
64     }
65 }
66 
operator =(const HapByteBuffer & other)67 HapByteBuffer& HapByteBuffer::operator=(const HapByteBuffer& other)
68 {
69     if (&other == this) {
70         return *this;
71     }
72 
73     buffer.reset(nullptr);
74     Init(other.GetCapacity());
75     if (buffer != nullptr && other.GetBufferPtr() != nullptr && capacity > 0) {
76         if (memcpy_s(buffer.get(), capacity, other.GetBufferPtr(), other.GetCapacity()) != EOK) {
77             HAPVERIFY_LOG_ERROR("memcpy_s failed");
78             return *this;
79         }
80         position = other.GetPosition();
81         limit = other.GetLimit();
82     }
83     return *this;
84 }
85 
CheckInputForGettingData(int32_t index,int32_t dataLen)86 bool HapByteBuffer::CheckInputForGettingData(int32_t index, int32_t dataLen)
87 {
88     if (buffer == nullptr) {
89         HAPVERIFY_LOG_ERROR("buffer is nullptr");
90         return false;
91     }
92     if (index < 0) {
93         HAPVERIFY_LOG_ERROR("invalid index %{public}d", index);
94         return false;
95     }
96     long long getDataLast = static_cast<long long>(position) + static_cast<long long>(index) +
97         static_cast<long long>(dataLen);
98     if (getDataLast > static_cast<long long>(limit)) {
99         HAPVERIFY_LOG_ERROR("position %{public}d, index  %{public}d, limit %{public}d",
100             position, index, limit);
101         return false;
102     }
103     return true;
104 }
105 
GetInt64(long long & value)106 bool HapByteBuffer::GetInt64(long long& value)
107 {
108     if (!GetInt64(0, value)) {
109         HAPVERIFY_LOG_ERROR("GetInt64 failed");
110         return false;
111     }
112     position += sizeof(long long);
113     return true;
114 }
115 
GetInt64(int32_t index,long long & value)116 bool HapByteBuffer::GetInt64(int32_t index, long long& value)
117 {
118     if (!CheckInputForGettingData(index, sizeof(long long))) {
119         HAPVERIFY_LOG_ERROR("Failed to get Int64");
120         return false;
121     }
122 
123     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(long long)) != EOK) {
124         HAPVERIFY_LOG_ERROR("memcpy_s failed");
125         return false;
126     }
127     return true;
128 }
129 
GetCapacity() const130 int32_t HapByteBuffer::GetCapacity() const
131 {
132     return capacity;
133 }
134 
GetBufferPtr() const135 const char* HapByteBuffer::GetBufferPtr() const
136 {
137     return buffer.get();
138 }
139 
GetInt32(int32_t & value)140 bool HapByteBuffer::GetInt32(int32_t& value)
141 {
142     if (!GetInt32(0, value)) {
143         HAPVERIFY_LOG_ERROR("GetInt32 failed");
144         return false;
145     }
146     position += sizeof(int32_t);
147     return true;
148 }
149 
GetInt32(int32_t index,int32_t & value)150 bool HapByteBuffer::GetInt32(int32_t index, int32_t& value)
151 {
152     if (!CheckInputForGettingData(index, sizeof(int32_t))) {
153         HAPVERIFY_LOG_ERROR("Failed to get Int32");
154         return false;
155     }
156 
157     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int32_t)) != EOK) {
158         HAPVERIFY_LOG_ERROR("memcpy_s failed");
159         return false;
160     }
161     return true;
162 }
163 
GetUInt32(int32_t index,uint32_t & value)164 bool HapByteBuffer::GetUInt32(int32_t index, uint32_t& value)
165 {
166     if (!CheckInputForGettingData(index, sizeof(uint32_t))) {
167         HAPVERIFY_LOG_ERROR("Failed to get UInt32");
168         return false;
169     }
170 
171     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(uint32_t)) != EOK) {
172         HAPVERIFY_LOG_ERROR("memcpy_s failed");
173         return false;
174     }
175     return true;
176 }
177 
GetUInt32(uint32_t & value)178 bool HapByteBuffer::GetUInt32(uint32_t& value)
179 {
180     if (!GetUInt32(0, value)) {
181         HAPVERIFY_LOG_ERROR("GetUInt32 failed");
182         return false;
183     }
184     position += sizeof(uint32_t);
185     return true;
186 }
187 
GetUInt16(int32_t index,uint16_t & value)188 bool HapByteBuffer::GetUInt16(int32_t index, uint16_t& value)
189 {
190     if (!CheckInputForGettingData(index, sizeof(uint16_t))) {
191         HAPVERIFY_LOG_ERROR("Failed to get UInt16");
192         return false;
193     }
194 
195     if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(uint16_t)) != EOK) {
196         HAPVERIFY_LOG_ERROR("memcpy_s failed");
197         return false;
198     }
199     return true;
200 }
201 
PutInt32(int32_t offset,int32_t value)202 void HapByteBuffer::PutInt32(int32_t offset, int32_t value)
203 {
204     if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int32_t>(sizeof(value))) {
205         if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
206             HAPVERIFY_LOG_ERROR("memcpy_s failed");
207         }
208     }
209 }
210 
PutByte(int32_t offset,char value)211 void HapByteBuffer::PutByte(int32_t offset, char value)
212 {
213     if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int32_t>(sizeof(value))) {
214         if (memcpy_s((buffer.get() + offset), (limit - offset), (&value), sizeof(value)) != EOK) {
215             HAPVERIFY_LOG_ERROR("memcpy_s failed");
216         }
217     }
218 }
219 
PutData(int32_t offset,const char data[],int32_t len)220 void HapByteBuffer::PutData(int32_t offset, const char data[], int32_t len)
221 {
222     if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
223         if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
224             HAPVERIFY_LOG_ERROR("memcpy_s failed");
225         }
226     }
227 }
228 
SetPosition(int32_t pos)229 void HapByteBuffer::SetPosition(int32_t pos)
230 {
231     if (pos >= 0 && pos <= limit) {
232         position = pos;
233     }
234 }
235 
Slice()236 void HapByteBuffer::Slice()
237 {
238     if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
239         HAPVERIFY_LOG_ERROR("position %{public}d capacity %{public}d limit %{public}d error",
240             position, capacity, limit);
241         return;
242     }
243     int32_t newCapacity = limit - position;
244     std::unique_ptr<char[]> newBuffer = std::make_unique<char[]>(newCapacity);
245     if (memcpy_s(newBuffer.get(), newCapacity, (buffer.get() + position), (limit - position)) != EOK) {
246         HAPVERIFY_LOG_ERROR("memcpy_s failed");
247         return;
248     }
249     buffer.reset(newBuffer.release());
250     position = 0;
251     capacity = newCapacity;
252     limit = capacity;
253 }
254 
GetPosition() const255 int32_t HapByteBuffer::GetPosition() const
256 {
257     return position;
258 }
259 
GetLimit() const260 int32_t HapByteBuffer::GetLimit() const
261 {
262     return limit;
263 }
264 
SetLimit(int32_t lim)265 void HapByteBuffer::SetLimit(int32_t lim)
266 {
267     if (lim <= capacity && lim >= position) {
268         limit = lim;
269     }
270 }
271 
Remaining() const272 int32_t HapByteBuffer::Remaining() const
273 {
274     return limit - position;
275 }
276 
HasRemaining() const277 bool HapByteBuffer::HasRemaining() const
278 {
279     return position < limit;
280 }
281 
Clear()282 void HapByteBuffer::Clear()
283 {
284     position = 0;
285     limit = capacity;
286 }
287 
IsEqual(const HapByteBuffer & other)288 bool HapByteBuffer::IsEqual(const HapByteBuffer& other)
289 {
290     if (&other == this) {
291         return true;
292     }
293     if (capacity != other.GetCapacity() || other.GetBufferPtr() == nullptr || buffer == nullptr) {
294         HAPVERIFY_LOG_ERROR("invalid input");
295         return false;
296     }
297     const char* otherBuffer = other.GetBufferPtr();
298     for (int32_t i = 0; i < capacity; i++) {
299         if (buffer[i] != otherBuffer[i]) {
300             HAPVERIFY_LOG_ERROR("diff value[%{public}d]: %{public}x %{public}x",
301                 i, buffer[i], otherBuffer[i]);
302             return false;
303         }
304     }
305     return true;
306 }
307 
IsEqual(const std::string & other)308 bool HapByteBuffer::IsEqual(const std::string& other)
309 {
310     if (capacity != static_cast<int32_t>(other.size()) || buffer == nullptr) {
311         HAPVERIFY_LOG_ERROR("invalid input");
312         return false;
313     }
314     for (int32_t i = 0; i < capacity; i++) {
315         if (buffer[i] != other[i]) {
316             HAPVERIFY_LOG_ERROR("diff value[%{public}d]: %{public}x %{public}x",
317                 i, buffer[i], other[i]);
318             return false;
319         }
320     }
321     return true;
322 }
323 
SetCapacity(int32_t cap)324 void HapByteBuffer::SetCapacity(int32_t cap)
325 {
326     if (buffer != nullptr) {
327         buffer.reset(nullptr);
328         position = 0;
329         limit = 0;
330         capacity = 0;
331     }
332     Init(cap);
333 }
334 } // namespace Verify
335 } // namespace Security
336 } // namespace OHOS
337