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