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 int HapByteBuffer::MAX_PRINT_LENGTH = 200;
25 const int HapByteBuffer::HEX_PRINT_LENGTH = 3;
26
HapByteBuffer()27 HapByteBuffer::HapByteBuffer() : buffer(nullptr), position(0), limit(0), capacity(0)
28 {
29 }
30
HapByteBuffer(int bufferCapacity)31 HapByteBuffer::HapByteBuffer(int 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(LABEL, "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(int bufferCapacity)54 void HapByteBuffer::Init(int 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(LABEL, "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(LABEL, "memcpy_s failed");
78 return *this;
79 }
80 position = other.GetPosition();
81 limit = other.GetLimit();
82 }
83 return *this;
84 }
85
CheckInputForGettingData(int index,int dataLen)86 bool HapByteBuffer::CheckInputForGettingData(int index, int dataLen)
87 {
88 if (buffer == nullptr) {
89 HAPVERIFY_LOG_ERROR(LABEL, "buffer is nullptr");
90 return false;
91 }
92 if (index < 0) {
93 HAPVERIFY_LOG_ERROR(LABEL, "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(LABEL, "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(LABEL, "GetInt64 failed");
110 return false;
111 }
112 position += sizeof(long long);
113 return true;
114 }
115
GetInt64(int index,long long & value)116 bool HapByteBuffer::GetInt64(int index, long long& value)
117 {
118 if (!CheckInputForGettingData(index, sizeof(long long))) {
119 HAPVERIFY_LOG_ERROR(LABEL, "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(LABEL, "memcpy_s failed");
125 return false;
126 }
127 return true;
128 }
129
GetCapacity() const130 int HapByteBuffer::GetCapacity() const
131 {
132 return capacity;
133 }
134
GetBufferPtr() const135 const char* HapByteBuffer::GetBufferPtr() const
136 {
137 return buffer.get();
138 }
139
GetInt32(int & value)140 bool HapByteBuffer::GetInt32(int& value)
141 {
142 if (!GetInt32(0, value)) {
143 HAPVERIFY_LOG_ERROR(LABEL, "GetInt32 failed");
144 return false;
145 }
146 position += sizeof(int);
147 return true;
148 }
149
GetInt32(int index,int & value)150 bool HapByteBuffer::GetInt32(int index, int& value)
151 {
152 if (!CheckInputForGettingData(index, sizeof(int))) {
153 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get Int32");
154 return false;
155 }
156
157 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(int)) != EOK) {
158 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
159 return false;
160 }
161 return true;
162 }
163
GetUInt32(int index,unsigned int & value)164 bool HapByteBuffer::GetUInt32(int index, unsigned int& value)
165 {
166 if (!CheckInputForGettingData(index, sizeof(unsigned int))) {
167 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt32");
168 return false;
169 }
170
171 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(unsigned int)) != EOK) {
172 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
173 return false;
174 }
175 return true;
176 }
177
GetUInt16(int index,unsigned short & value)178 bool HapByteBuffer::GetUInt16(int index, unsigned short& value)
179 {
180 if (!CheckInputForGettingData(index, sizeof(unsigned short))) {
181 HAPVERIFY_LOG_ERROR(LABEL, "Failed to get UInt16");
182 return false;
183 }
184
185 if (memcpy_s(&value, sizeof(value), (buffer.get() + position + index), sizeof(unsigned short)) != EOK) {
186 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
187 return false;
188 }
189 return true;
190 }
191
PutInt32(int offset,int value)192 void HapByteBuffer::PutInt32(int offset, int value)
193 {
194 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int>(sizeof(value))) {
195 if (memcpy_s((buffer.get() + offset), (limit - offset), &value, sizeof(value)) != EOK) {
196 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
197 }
198 }
199 }
200
PutByte(int offset,char value)201 void HapByteBuffer::PutByte(int offset, char value)
202 {
203 if (buffer != nullptr && offset >= 0 && limit - offset >= static_cast<int>(sizeof(value))) {
204 if (memcpy_s((buffer.get() + offset), (limit - offset), (&value), sizeof(value)) != EOK) {
205 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
206 }
207 }
208 }
209
PutData(int offset,const char data[],int len)210 void HapByteBuffer::PutData(int offset, const char data[], int len)
211 {
212 if (buffer != nullptr && data != nullptr && offset >= 0 && len > 0 && (limit - offset) >= len) {
213 if (memcpy_s((buffer.get() + offset), (limit - offset), data, len) != EOK) {
214 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
215 }
216 }
217 }
218
SetPosition(int pos)219 void HapByteBuffer::SetPosition(int pos)
220 {
221 if (pos >= 0 && pos <= limit) {
222 position = pos;
223 }
224 }
225
Slice()226 void HapByteBuffer::Slice()
227 {
228 if (position >= capacity || limit > capacity || position >= limit || buffer == nullptr) {
229 HAPVERIFY_LOG_ERROR(LABEL, "position %{public}d capacity %{public}d limit %{public}d error",
230 position, capacity, limit);
231 return;
232 }
233 int newCapacity = limit - position;
234 std::unique_ptr<char[]> newBuffer = std::make_unique<char[]>(newCapacity);
235 if (memcpy_s(newBuffer.get(), newCapacity, (buffer.get() + position), (limit - position)) != EOK) {
236 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
237 return;
238 }
239 buffer.reset(newBuffer.release());
240 position = 0;
241 capacity = newCapacity;
242 limit = capacity;
243 }
244
GetPosition() const245 int HapByteBuffer::GetPosition() const
246 {
247 return position;
248 }
249
GetLimit() const250 int HapByteBuffer::GetLimit() const
251 {
252 return limit;
253 }
254
SetLimit(int lim)255 void HapByteBuffer::SetLimit(int lim)
256 {
257 if (lim <= capacity && lim >= position) {
258 limit = lim;
259 }
260 }
261
Remaining() const262 int HapByteBuffer::Remaining() const
263 {
264 return limit - position;
265 }
266
HasRemaining() const267 bool HapByteBuffer::HasRemaining() const
268 {
269 return position < limit;
270 }
271
CopyPartialBuffer(const HapByteBuffer & other,int len)272 bool HapByteBuffer::CopyPartialBuffer(const HapByteBuffer& other, int len)
273 {
274 int readableDataLen = other.Remaining();
275 if (readableDataLen < len) {
276 HAPVERIFY_LOG_ERROR(LABEL, "readableDataLen %{public}d less than len %{public}d", readableDataLen, len);
277 return false;
278 }
279
280 buffer.reset(nullptr);
281 buffer = std::make_unique<char[]>(len);
282 if (buffer != nullptr && other.GetBufferPtr() != nullptr) {
283 capacity = len;
284 limit = capacity;
285 if (memcpy_s(buffer.get(), capacity, (other.GetBufferPtr() + other.GetPosition()), len) != EOK) {
286 HAPVERIFY_LOG_ERROR(LABEL, "memcpy_s failed");
287 return false;
288 }
289 }
290 position = 0;
291 return true;
292 }
293
Clear()294 void HapByteBuffer::Clear()
295 {
296 position = 0;
297 limit = capacity;
298 }
299
IsEqual(const HapByteBuffer & other)300 bool HapByteBuffer::IsEqual(const HapByteBuffer& other)
301 {
302 if (&other == this) {
303 return true;
304 }
305 if (capacity != other.GetCapacity() || other.GetBufferPtr() == nullptr || buffer == nullptr) {
306 HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
307 return false;
308 }
309 const char* otherBuffer = other.GetBufferPtr();
310 for (int i = 0; i < capacity; i++) {
311 if (buffer[i] != otherBuffer[i]) {
312 HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
313 i, buffer[i], otherBuffer[i]);
314 return false;
315 }
316 }
317 return true;
318 }
319
IsEqual(const std::string & other)320 bool HapByteBuffer::IsEqual(const std::string& other)
321 {
322 if (capacity != static_cast<int>(other.size()) || buffer == nullptr) {
323 HAPVERIFY_LOG_ERROR(LABEL, "invalid input");
324 return false;
325 }
326 for (int i = 0; i < capacity; i++) {
327 if (buffer[i] != other[i]) {
328 HAPVERIFY_LOG_ERROR(LABEL, "diff value[%{public}d]: %{public}x %{public}x",
329 i, buffer[i], other[i]);
330 return false;
331 }
332 }
333 return true;
334 }
335
SetCapacity(int cap)336 void HapByteBuffer::SetCapacity(int cap)
337 {
338 if (buffer != nullptr) {
339 buffer.reset(nullptr);
340 position = 0;
341 limit = 0;
342 capacity = 0;
343 }
344 Init(cap);
345 }
346 } // namespace Verify
347 } // namespace Security
348 } // namespace OHOS
349