1 /*
2 * Copyright (c) 2025 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 "commoncompbaseutf_fuzzer.h"
17 #include "common_components/base/utf_helper.h"
18 #include "test/fuzztest/containersdequecommon_fuzzer/containersdequecommon_fuzzer.h"
19
20 using namespace common::utf_helper;
21
22 namespace OHOS {
UtfHelperGetValueFromTwoHex(const uint8_t * data,size_t size)23 void UtfHelperGetValueFromTwoHex(const uint8_t* data, size_t size)
24 {
25 if (size == 0) {
26 return;
27 }
28 GetValueFromTwoHex('0' + data[size - 1] % 10, // 10: val in [0x0, 0x9], convert to ['0', '9']
29 'a' + data[size - 1] % 6); // 6:val in ['a', 'f'], convert to ['a', 'f']
30 }
31
UtfHelperGetHexChar16(const uint8_t * data,size_t size)32 void UtfHelperGetHexChar16(const uint8_t* data, size_t size)
33 {
34 if (size == 0) {
35 return;
36 }
37 GetHexChar16(data[size - 1] % 0xff); // 0xff: Maximum value of uint8
38 }
39
UtfHelperCombineTwoU16(const uint8_t * data,size_t size)40 void UtfHelperCombineTwoU16(const uint8_t* data, size_t size)
41 {
42 if (size == 0) {
43 return;
44 }
45 CombineTwoU16(data[size - 1] % 0xff, (size / 2) % 0xff); // 2:half of the size,0xff: Maximum value of uint8
46 }
47
UtfHelperUTF16Decode(const uint8_t * data,size_t size)48 void UtfHelperUTF16Decode(const uint8_t* data, size_t size)
49 {
50 if (size == 0) {
51 return;
52 }
53 uint16_t lead = DECODE_LEAD_LOW + data[size - 1] % (DECODE_LEAD_HIGH - DECODE_LEAD_LOW);
54 uint16_t tail = DECODE_TRAIL_LOW + data[size - 1] % (DECODE_TRAIL_HIGH - DECODE_TRAIL_LOW);
55
56 UTF16Decode(lead, tail);
57 }
58
UtfHelperDebuggerConvertRegionUtf16ToUtf8(const uint8_t * data,size_t size)59 void UtfHelperDebuggerConvertRegionUtf16ToUtf8(const uint8_t* data, size_t size)
60 {
61 if (size == 0) {
62 return;
63 }
64 size_t utf16Len = 8; // 8:length of u16
65 size_t utf8Len = 100; // 100:buff len
66 size_t start = 0;
67 bool modify = ((data[size - 1] % 2 == 0) ? true : false); // 2:Check size is an even number
68 uint16_t utf16Value[8] = {
69 0x00, // 0 or 2 (special case for \u0000 ==> C080 - 1100'0000 1000'0000)
70 0x7F, // 1(0x00, 0x7F]
71 0x7FF, // 2 [0x80, 0x7FF]
72 0x800, // 3 [0x800, 0xD7FF]
73 0xD800, // 3 [0xD800, 0xDFFF]
74 0xFFFF, // 3 [0xE000, 0xFFFF]
75 0xD800, 0xDFFF}; // 4 [0x10000, 0x10FFFF]
76 const uint16_t *utf16ValuePtr = utf16Value;
77 uint8_t *utf8Out = (uint8_t*)malloc(utf8Len);
78 DebuggerConvertRegionUtf16ToUtf8(utf16ValuePtr, utf8Out, utf16Len, utf8Len, start, modify);
79 free(utf8Out);
80 }
81
UtfHelperConvertUtf8ToUtf16Pair(const uint8_t * data,size_t size)82 void UtfHelperConvertUtf8ToUtf16Pair(const uint8_t* data, size_t size)
83 {
84 if (size == 0) {
85 return;
86 }
87 uint8_t utf8Value1[1] = {0x0};
88 const uint8_t *utf8ValuePtr1 = utf8Value1;
89 ConvertUtf8ToUtf16Pair(utf8ValuePtr1, (data[size - 1] % 2) == 0); // 2:Check size is even number
90
91 uint8_t utf8Value2[1] = {UTF8_1B_MAX}; // 1: array len
92 const uint8_t *utf8ValuePtr2 = utf8Value2;
93 ConvertUtf8ToUtf16Pair(utf8ValuePtr1, (data[size - 1] % 2) == 1); // 2:Check size is even number
94 }
95
UtfHelperConvertUtf8ToUnicodeChar(const uint8_t * data,size_t size)96 void UtfHelperConvertUtf8ToUnicodeChar(const uint8_t* data, size_t size)
97 {
98 if (size == 0) {
99 return;
100 }
101 uint8_t utf8Value11[4] = {0xF4, 0x80, 0x80, 0x40}; // invalid
102 const uint8_t *utf8ValuePtr11 = utf8Value11;
103 ConvertUtf8ToUnicodeChar(utf8ValuePtr11, static_cast<UtfLength>(data[size - 1] % 4)); // 4: lenth of array
104 }
105
UtfHelperConvertUtf16ToUtf8(const uint8_t * data,size_t size)106 void UtfHelperConvertUtf16ToUtf8(const uint8_t* data, size_t size)
107 {
108 if (size == 0) {
109 return;
110 }
111 uint16_t utf16Data0[5] = {0x0, 0x7f, 0x7ff, 0xd800, 0xdfff}; // invalid
112 uint16_t utf16Data1[2] = {LO_SURROGATE_MIN + 1, LO_SURROGATE_MAX - 1};
113 ConvertUtf16ToUtf8(utf16Data0[data[size - 1] % 5], // 5:length of utf16Data0
114 utf16Data1[data[size - 1] % 2], (data[size - 1] % 2) == 1, // 2:Check size is even number
115 (data[size - 1] % 3) >= 2); // 3:Get Remainder
116 }
117
UtfHelperIsValidUTF8(const uint8_t * data,size_t size)118 void UtfHelperIsValidUTF8(const uint8_t* data, size_t size)
119 {
120 if (size == 0) {
121 return;
122 }
123 const std::vector<uint8_t> utfDataFourBitVaild = {BIT_MASK_4, BIT_MASK_1 + 0x10, BIT_MASK_1, BIT_MASK_1};
124
125 std::vector<uint8_t> tmpUtfData;
126 size_t vecLen = (data[size - 1] % 4 == 0 ? 1 : data[size - 1] % 4); // 4:number of utfDataFourBitVaild array
127 for (size_t i = 0; i < vecLen; ++i) {
128 tmpUtfData.push_back(utfDataFourBitVaild[i]);
129 }
130 common::utf_helper::IsValidUTF8(tmpUtfData);
131 }
132 }
133
134
135 // Fuzzer entry point.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)136 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
137 {
138 // Run your code on data.
139 OHOS::UtfHelperGetValueFromTwoHex(data, size);
140 OHOS::UtfHelperGetHexChar16(data, size);
141
142 OHOS::UtfHelperCombineTwoU16(data, size);
143 OHOS::UtfHelperUTF16Decode(data, size);
144 OHOS::UtfHelperDebuggerConvertRegionUtf16ToUtf8(data, size);
145 OHOS::UtfHelperConvertUtf8ToUtf16Pair(data, size);
146 OHOS::UtfHelperConvertUtf8ToUnicodeChar(data, size);
147 OHOS::UtfHelperConvertUtf16ToUtf8(data, size);
148 OHOS::UtfHelperIsValidUTF8(data, size);
149
150 return 0;
151 }