1 /*
2  * Copyright (c) 2022 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 "js_buffer.h"
17 
18 #include <cmath>
19 #include <iostream>
20 
21 #include "securec.h"
22 
23 using namespace std;
24 
25 namespace OHOS::buffer {
Init(uint32_t size)26 void Buffer::Init(uint32_t size)
27 {
28     raw_ = reinterpret_cast<uint8_t *>(malloc(size));
29     if (raw_ == nullptr) {
30         HILOG_FATAL("Buffer constructor malloc failed");
31         length_ = 0;
32     } else {
33         length_ = size;
34     }
35 }
36 
Init(Buffer * buffer)37 void Buffer::Init(Buffer *buffer)
38 {
39     if (buffer != nullptr && buffer->length_ > 0) {
40         this->raw_ = reinterpret_cast<uint8_t *>(malloc(buffer->length_));
41         if (raw_ == nullptr) {
42             HILOG_FATAL("Buffer constructor malloc failed");
43         } else {
44             this->length_ = buffer->length_;
45             if (memcpy_s(raw_, length_, buffer->raw_ + buffer->byteOffset_, length_) != EOK) {
46                 HILOG_FATAL("Buffer constructor memcpy_s failed");
47             }
48         }
49     }
50 }
51 
Init(Buffer * pool,unsigned int poolOffset,unsigned int length)52 void Buffer::Init(Buffer *pool, unsigned int poolOffset, unsigned int length)
53 {
54     if (pool != nullptr) {
55         this->raw_ = pool->GetRaw();
56         this->byteOffset_ = poolOffset;
57         this->length_ = length;
58     }
59     this->needRelease_ = false;
60 }
61 
Init(uint8_t * buffer,unsigned int byteOffset,unsigned int length)62 void Buffer::Init(uint8_t *buffer, unsigned int byteOffset, unsigned int length)
63 {
64     if (buffer != nullptr) {
65         this->raw_ = buffer;
66         this->length_ = length;
67         this->byteOffset_ = byteOffset;
68     }
69     this->needRelease_ = false;
70 }
71 
~Buffer()72 Buffer::~Buffer()
73 {
74     if (raw_ != nullptr && needRelease_) {
75         free(raw_);
76         raw_ = nullptr;
77     }
78 }
79 
GetEncodingType(std::string encode)80 EncodingType Buffer::GetEncodingType(std::string encode)
81 {
82     if (encode == "hex") {
83         return HEX;
84     } else if (encode == "base64url") {
85         return BASE64URL;
86     } else if (encode == "ascii") {
87         return ASCII;
88     } else if (encode == "base64") {
89         return BASE64;
90     } else if (encode == "latin1") {
91         return LATIN1;
92     } else if (encode == "binary") {
93         return BINARY;
94     } else if (encode == "utf16le") {
95         return UTF16LE;
96     } else {
97         return UTF8;
98     }
99 }
100 
GetRaw()101 uint8_t *Buffer::GetRaw()
102 {
103     return raw_;
104 }
105 
GetLength()106 unsigned int Buffer::GetLength()
107 {
108     return length_;
109 }
110 
SetLength(unsigned int len)111 void Buffer::SetLength(unsigned int len)
112 {
113     length_ = len;
114 }
115 
GetByteOffset()116 unsigned int Buffer::GetByteOffset()
117 {
118     return byteOffset_;
119 }
120 
SubBuffer(Buffer * tBuf,uint32_t start,uint32_t end)121 void Buffer::SubBuffer(Buffer *tBuf, uint32_t start, uint32_t end)
122 {
123     if (tBuf == nullptr) {
124         HILOG_ERROR("buffer: buffer is nullptr.");
125         return;
126     }
127     this->Init(tBuf->GetRaw(), tBuf->byteOffset_ + start, (end - start));
128 }
129 
Copy(Buffer * tBuf,uint32_t tStart,uint32_t sStart,uint32_t sEnd)130 uint32_t Buffer::Copy(Buffer *tBuf, uint32_t tStart, uint32_t sStart, uint32_t sEnd)
131 {
132     if (tBuf == nullptr) {
133         return 0; // 0 : cannot copy anything
134     }
135     uint8_t *dest = tBuf->raw_ + tBuf->byteOffset_ + tStart;
136     uint32_t tLength = tBuf->length_ - tStart;
137     uint8_t *src = this->raw_ + this->byteOffset_ + sStart;
138     uint32_t sLength = sEnd - sStart;
139     uint32_t len = tLength > sLength ? sLength : tLength;
140     if (tBuf->raw_ == this->raw_) {
141         if (src == nullptr || dest == nullptr) {
142             return len;
143         }
144         if (len == 0) {
145             HILOG_DEBUG("Buffer::WriteBytes size is 0");
146             return len;
147         }
148         if (memmove_s(dest, len, src, len) != EOK) {
149             HILOG_FATAL("Buffer WriteBytes memmove_s failed");
150             return len;
151         }
152     } else {
153         WriteBytes(src, len, dest);
154     }
155     return len;
156 }
157 
Compare(Buffer * tBuf,uint32_t targetStart,uint32_t sourceStart,uint32_t length)158 int Buffer::Compare(Buffer *tBuf, uint32_t targetStart, uint32_t sourceStart, uint32_t length)
159 {
160     if (tBuf == nullptr) {
161         return 0;
162     }
163     uint8_t *dest = tBuf->GetRaw() + tBuf->byteOffset_ + targetStart;
164     uint8_t *src = this->GetRaw() + this->byteOffset_ + sourceStart;
165     return memcmp(dest, src, length);
166 }
167 
WriteBE(int32_t value,uint32_t bytes)168 void Buffer::WriteBE(int32_t value, uint32_t bytes)
169 {
170     uint32_t uValue = static_cast<uint32_t>(value);
171     for (uint32_t i = bytes; i > 0; i--) {
172         uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
173         data_[i - 1] = va;
174         // 8 : shift right 8 bits(i.e 1 byte)
175         uValue = uValue >> 8;
176     }
177 }
178 
WriteLE(int32_t value,uint32_t bytes)179 void Buffer::WriteLE(int32_t value, uint32_t bytes)
180 {
181     uint32_t uValue = static_cast<uint32_t>(value);
182     for (uint32_t i = 0, len = bytes - 1; i <= len; i++) {
183         uint8_t va = static_cast<uint8_t>(uValue & 0x000000FF);
184         data_[i] = va;
185         // 8 : shift right 8 bits(i.e 1 byte)
186         uValue = uValue >> 8;
187     }
188 }
189 
ReadBE(uint32_t bytes)190 uint32_t Buffer::ReadBE(uint32_t bytes)
191 {
192     uint32_t result = 0x0000;
193     for (uint32_t i = 0; i < bytes; i++) {
194         // 8 : shift left 8 bits(i.e 1 byte)
195         result = result << 8;
196         result |= data_[i];
197     }
198     return result;
199 }
200 
ReadLE(uint32_t bytes)201 uint32_t Buffer::ReadLE(uint32_t bytes)
202 {
203     uint32_t result = 0x0000;
204     for (uint32_t i = bytes; i > 0; i--) {
205         // 8 : shift left 8 bits(i.e 1 byte)
206         result = result << 8;
207         result |= data_[i - 1];
208     }
209     return result;
210 }
211 
WriteInt32BE(int32_t value,uint32_t offset)212 void Buffer::WriteInt32BE(int32_t value, uint32_t offset)
213 {
214     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
215     WriteBE(value, 4);
216     // 4 : write 4 bytes
217     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
218 }
219 
ReadInt32BE(uint32_t offset)220 int32_t Buffer::ReadInt32BE(uint32_t offset)
221 {
222     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
223     ReadBytes(data_, offset, 4);
224     // 4 : read 4 bytes
225     return static_cast<int32_t>(ReadBE(4));
226 }
227 
WriteInt32LE(int32_t value,uint32_t offset)228 void Buffer::WriteInt32LE(int32_t value, uint32_t offset)
229 {
230     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
231     WriteLE(value, 4);
232     // 4 : write 4 bytes
233     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
234 }
235 
ReadInt32LE(uint32_t offset)236 int32_t Buffer::ReadInt32LE(uint32_t offset)
237 {
238     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
239     ReadBytes(data_, offset, 4);
240     // 4 : read 4 bytes
241     return static_cast<int32_t>(ReadLE(4));
242 }
243 
WriteUInt32BE(int32_t value,uint32_t offset)244 void Buffer::WriteUInt32BE(int32_t value, uint32_t offset)
245 {
246     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
247     WriteBE(value, 4);
248     // 4 : write 4 bytes
249     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
250 }
251 
ReadUInt32BE(uint32_t offset)252 uint32_t Buffer::ReadUInt32BE(uint32_t offset)
253 {
254     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
255     ReadBytes(data_, offset, 4);
256     // 4 : read 4 bytes
257     return ReadBE(4);
258 }
259 
WriteUInt32LE(int32_t value,uint32_t offset)260 void Buffer::WriteUInt32LE(int32_t value, uint32_t offset)
261 {
262     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
263     WriteLE(value, 4);
264     // 4 : write 4 bytes
265     WriteBytes(data_, 4, raw_ + byteOffset_ + offset);
266 }
267 
ReadUInt32LE(uint32_t offset)268 uint32_t Buffer::ReadUInt32LE(uint32_t offset)
269 {
270     // 4 : 4 bytes(i.e 4 * 8 = 32 bits)
271     ReadBytes(data_, offset, 4);
272     // 4 : read 4 bytes
273     return ReadLE(4);
274 }
275 
Get(uint32_t index)276 int32_t Buffer::Get(uint32_t index)
277 {
278     uint8_t value;
279     uint32_t count = 1;
280     if (memcpy_s(&value, count, raw_ + byteOffset_ + index, count) != EOK) {
281         HILOG_FATAL("Buffer get memcpy_s failed");
282     }
283     return value;
284 }
285 
Set(uint32_t index,uint8_t value)286 void Buffer::Set(uint32_t index, uint8_t value)
287 {
288     WriteByte(value, index);
289 }
290 
ReadBytes(uint8_t * data,uint32_t offset,uint32_t length)291 void Buffer::ReadBytes(uint8_t *data, uint32_t offset, uint32_t length)
292 {
293     if (data == nullptr) {
294         return;
295     }
296 
297     if (length == 0) {
298         HILOG_DEBUG("Buffer::ReadBytes size is 0");
299         return;
300     }
301     if (memcpy_s(data, length, raw_ + byteOffset_ + offset, length) != EOK) {
302         HILOG_FATAL("Buffer ReadBytes memcpy_s failed");
303     }
304 }
305 
ReadBytesForArrayBuffer(void * data,uint32_t length)306 void Buffer::ReadBytesForArrayBuffer(void *data, uint32_t length)
307 {
308     if (length == 0) {
309         HILOG_DEBUG("Buffer::ReadBytesForArrayBuffer size is 0");
310         return;
311     }
312     if (memcpy_s(data, length, reinterpret_cast<const void*>(raw_ + byteOffset_), length) != EOK) {
313         HILOG_ERROR("copy raw to arraybuffer error");
314         return;
315     }
316 }
317 
WriteByte(uint8_t number,uint32_t offset)318 void Buffer::WriteByte(uint8_t number, uint32_t offset)
319 {
320     WriteBytes(&number, 1, raw_ + byteOffset_ + offset);
321 }
322 
WriteString(std::string value,unsigned int size)323 unsigned int Buffer::WriteString(std::string value, unsigned int size)
324 {
325     uint8_t *str = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data()));
326     bool isWriteSuccess = WriteBytes(str, size, raw_ + byteOffset_);
327     return isWriteSuccess ? size : 0; // 0: write failed
328 }
329 
WriteString(string value,unsigned int offset,unsigned int length)330 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int length)
331 {
332     uint8_t *str = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data()));
333     bool isWriteSuccess = WriteBytes(str, length, raw_ + byteOffset_ + offset);
334     return isWriteSuccess ? length : 0; // 0: write failed
335 }
336 
WriteStringLoop(string value,unsigned int offset,unsigned int end,unsigned int length)337 void Buffer::WriteStringLoop(string value, unsigned int offset, unsigned int end, unsigned int length)
338 {
339     if (end - offset <= 0 || value.length() == 0) {
340         return;
341     }
342     unsigned int loop = length > end - offset ? end - offset : length;
343 
344     uint8_t *str = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data()));
345     while (offset < end) {
346         if (loop + offset > end) {
347             WriteBytes(str, end - offset, raw_ + byteOffset_ + offset);
348         } else {
349             WriteBytes(str, loop, raw_ + byteOffset_ + offset);
350         }
351         offset += loop;
352     }
353 }
354 
Utf16StrToStr(std::u16string value)355 std::string Buffer::Utf16StrToStr(std::u16string value)
356 {
357     string str = "";
358     char16_t *data = const_cast<char16_t *>(reinterpret_cast<const char16_t *>(value.data()));
359     for (unsigned int i = 0; i < value.length(); i++) {
360         char16_t c = data[i];
361         char high = static_cast<char>((c >> 8) & 0x00FF);
362         char low = static_cast<char>(c & 0x00FF);
363         str.push_back(low);
364         str.push_back(high);
365     }
366     return str;
367 }
368 
WriteString(std::u16string value,unsigned int offset,unsigned int length)369 unsigned int Buffer::WriteString(std::u16string value, unsigned int offset, unsigned int length)
370 {
371     string str = Utf16StrToStr(value);
372     return this->WriteString(str, offset, length);
373 }
374 
WriteStringLoop(std::u16string value,unsigned int offset,unsigned int end)375 void Buffer::WriteStringLoop(std::u16string value, unsigned int offset, unsigned int end)
376 {
377     string str = Utf16StrToStr(value);
378     // 2 : utf16 is 2 times of length of ascii
379     this->WriteStringLoop(str, offset, end, value.length() * 2);
380 }
381 
WriteBytes(uint8_t * src,unsigned int size,uint8_t * dest)382 bool Buffer::WriteBytes(uint8_t *src, unsigned int size, uint8_t *dest)
383 {
384     if (src == nullptr || dest == nullptr) {
385         return false;
386     }
387     if (size == 0) {
388         HILOG_DEBUG("Buffer::WriteBytes size is 0");
389         return false;
390     }
391     if (memcpy_s(dest, size, src, size) != EOK) {
392         HILOG_FATAL("Buffer WriteBytes memcpy_s failed");
393         return false;
394     }
395     return true;
396 }
397 
SetArray(vector<uint8_t> array,unsigned int offset)398 void Buffer::SetArray(vector<uint8_t> array, unsigned int offset)
399 {
400     unsigned int arrLen = array.size();
401     unsigned int size = arrLen <= length_ ? arrLen : length_;
402     WriteBytes(array.data(), size, raw_ + byteOffset_ + offset);
403 }
404 
FillBuffer(Buffer * buffer,unsigned int offset,unsigned int end)405 void Buffer::FillBuffer(Buffer *buffer, unsigned int offset, unsigned int end)
406 {
407     if (buffer == nullptr) {
408         return;
409     }
410     if (end - offset <= 0) {
411         return;
412     }
413     unsigned int loop = buffer->GetLength() > end - offset ? end - offset : buffer->GetLength();
414 
415     while (offset < end) {
416         if (offset + loop > end) {
417             loop = end - offset;
418         }
419         WriteBytes(buffer->GetRaw() + buffer->byteOffset_, loop, raw_ + byteOffset_ + offset);
420         offset += loop;
421     }
422 }
423 
FillNumber(vector<uint8_t> numbers,unsigned int offset,unsigned int end)424 void Buffer::FillNumber(vector<uint8_t> numbers, unsigned int offset, unsigned int end)
425 {
426     if (end - offset <= 0) {
427         return;
428     }
429     unsigned int loop = numbers.size() > end - offset ? end - offset : numbers.size();
430 
431     while (offset < end) {
432         if (offset + loop > end) {
433             loop = end - offset;
434         }
435         WriteBytes(numbers.data(), loop, raw_ + byteOffset_ + offset);
436         offset += loop;
437     }
438 }
439 
GetString(std::string value,EncodingType encodingType)440 std::string Buffer::GetString(std::string value, EncodingType encodingType)
441 {
442     string str = "";
443     switch (encodingType) {
444         case ASCII:
445         case LATIN1:
446             str = Utf8ToUtf16BEToANSI(value);
447             break;
448         case UTF8:
449             str = value;
450             break;
451         case BASE64:
452         case BASE64URL:
453             str = Base64Decode(value, encodingType);
454             break;
455         case BINARY:
456             str = Utf8ToUtf16BEToANSI(value);
457             break;
458         default:
459             break;
460     }
461     return str;
462 }
463 
FillString(string value,unsigned int offset,unsigned int end,string encoding)464 void Buffer::FillString(string value, unsigned int offset, unsigned int end, string encoding)
465 {
466     EncodingType encodingType = GetEncodingType(encoding);
467     if (encodingType == UTF16LE) {
468         u16string u16Str = Utf8ToUtf16BE(value);
469         this->WriteStringLoop(u16Str, offset, end);
470     } else {
471         string str = GetString(value, encodingType);
472         this->WriteStringLoop(str, offset, end, str.length());
473     }
474 }
475 
WriteString(string value,unsigned int offset,unsigned int length,string encoding)476 unsigned int Buffer::WriteString(string value, unsigned int offset, unsigned int length, string encoding)
477 {
478     EncodingType encodingType = GetEncodingType(encoding);
479     unsigned int lengthWrote = 0;
480     if (encodingType == UTF16LE) {
481         u16string u16Str = Utf8ToUtf16BE(value);
482         lengthWrote = this->WriteString(u16Str, offset, length);
483     } else {
484         string str = GetString(value, encodingType);
485         lengthWrote = this->WriteString(str, offset, length);
486     }
487     return lengthWrote;
488 }
489 
ToBase64(uint32_t start,uint32_t length)490 std::string Buffer::ToBase64(uint32_t start, uint32_t length)
491 {
492     if (length == 0 || length >= UINT32_MAX) {
493         HILOG_ERROR("buffer::length is illegal");
494         return "";
495     }
496     uint8_t *data = new uint8_t[length];
497     if (data == nullptr) {
498         HILOG_ERROR("buffer:: memory allocation failed.");
499         return "";
500     }
501     ReadBytes(data, start, length);
502     std::string result = Base64Encode(reinterpret_cast<const unsigned char*>(data), length, BASE64);
503     delete[] data;
504     data = nullptr;
505     return result;
506 }
507 
ToBase64Url(uint32_t start,uint32_t length)508 std::string Buffer::ToBase64Url(uint32_t start, uint32_t length)
509 {
510     if (length == 0 || length >= UINT32_MAX) {
511         HILOG_ERROR("buffer::length is illegal");
512         return "";
513     }
514     uint8_t *data = new (std::nothrow) uint8_t[length];
515     if (data == nullptr) {
516         HILOG_ERROR("buffer:: memory allocation failed.");
517         return "";
518     }
519     ReadBytes(data, start, length);
520     std::string result = Base64Encode(reinterpret_cast<const unsigned char*>(data), length, BASE64URL);
521     delete[] data;
522     data = nullptr;
523     return result;
524 }
525 
IndexOf(const char * data,uint32_t offset,uint32_t len,uint64_t & resultIndex)526 int Buffer::IndexOf(const char *data, uint32_t offset, uint32_t len, uint64_t &resultIndex)
527 {
528     if (data == nullptr || length_ <= offset) {
529         return -1;
530     }
531     uint8_t *sData = new (std::nothrow) uint8_t[length_ - offset];
532     if (sData == nullptr) {
533         HILOG_ERROR("buffer:: memory allocation failed.");
534         return -1;
535     }
536     ReadBytes(sData, offset, length_ - offset);
537     int index = FindIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
538     if (index == -1) { // -1:The target to be searched does not exist
539         delete[] sData;
540         sData = nullptr;
541         return index;
542     } else {
543         resultIndex = static_cast<uint64_t>(offset) + static_cast<uint64_t>(index);
544         delete[] sData;
545         sData = nullptr;
546         return -2; // -2:The number of invalid data
547     }
548 }
549 
LastIndexOf(const char * data,uint32_t offset,uint32_t len)550 int Buffer::LastIndexOf(const char *data, uint32_t offset, uint32_t len)
551 {
552     if (data == nullptr || length_ <= offset) {
553         return -1;
554     }
555     uint8_t *sData = new (std::nothrow) uint8_t[length_ - offset];
556     if (sData == nullptr) {
557         HILOG_ERROR("buffer:: memory allocation failed.");
558         return -1;
559     }
560     ReadBytes(sData, offset, length_ - offset);
561     int result = FindLastIndex(sData, reinterpret_cast<uint8_t *>(const_cast<char *>(data)), length_ - offset, len);
562     delete[] sData;
563     sData = nullptr;
564     return result;
565 }
566 } // namespace OHOS::Buffer
567