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