* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "commoncompbaseutf_fuzzer.h"
#include "common_components/base/utf_helper.h"
#include "test/fuzztest/containersdequecommon_fuzzer/containersdequecommon_fuzzer.h"
using namespace common::utf_helper;
namespace OHOS {
void UtfHelperGetValueFromTwoHex(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
GetValueFromTwoHex('0' + data[size - 1] % 10,
'a' + data[size - 1] % 6);
}
void UtfHelperGetHexChar16(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
GetHexChar16(data[size - 1] % 0xff);
}
void UtfHelperCombineTwoU16(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
CombineTwoU16(data[size - 1] % 0xff, (size / 2) % 0xff);
}
void UtfHelperUTF16Decode(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
uint16_t lead = DECODE_LEAD_LOW + data[size - 1] % (DECODE_LEAD_HIGH - DECODE_LEAD_LOW);
uint16_t tail = DECODE_TRAIL_LOW + data[size - 1] % (DECODE_TRAIL_HIGH - DECODE_TRAIL_LOW);
UTF16Decode(lead, tail);
}
void UtfHelperDebuggerConvertRegionUtf16ToUtf8(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
size_t utf16Len = 8;
size_t utf8Len = 100;
size_t start = 0;
bool modify = ((data[size - 1] % 2 == 0) ? true : false);
uint16_t utf16Value[8] = {
0x00,
0x7F,
0x7FF,
0x800,
0xD800,
0xFFFF,
0xD800, 0xDFFF};
const uint16_t *utf16ValuePtr = utf16Value;
uint8_t *utf8Out = (uint8_t*)malloc(utf8Len);
DebuggerConvertRegionUtf16ToUtf8(utf16ValuePtr, utf8Out, utf16Len, utf8Len, start, modify);
free(utf8Out);
}
void UtfHelperConvertUtf8ToUtf16Pair(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
uint8_t utf8Value1[1] = {0x0};
const uint8_t *utf8ValuePtr1 = utf8Value1;
ConvertUtf8ToUtf16Pair(utf8ValuePtr1, (data[size - 1] % 2) == 0);
uint8_t utf8Value2[1] = {UTF8_1B_MAX};
const uint8_t *utf8ValuePtr2 = utf8Value2;
ConvertUtf8ToUtf16Pair(utf8ValuePtr1, (data[size - 1] % 2) == 1);
}
void UtfHelperConvertUtf8ToUnicodeChar(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
uint8_t utf8Value11[4] = {0xF4, 0x80, 0x80, 0x40};
const uint8_t *utf8ValuePtr11 = utf8Value11;
ConvertUtf8ToUnicodeChar(utf8ValuePtr11, static_cast<UtfLength>(data[size - 1] % 4));
}
void UtfHelperConvertUtf16ToUtf8(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
uint16_t utf16Data0[5] = {0x0, 0x7f, 0x7ff, 0xd800, 0xdfff};
uint16_t utf16Data1[2] = {LO_SURROGATE_MIN + 1, LO_SURROGATE_MAX - 1};
ConvertUtf16ToUtf8(utf16Data0[data[size - 1] % 5],
utf16Data1[data[size - 1] % 2], (data[size - 1] % 2) == 1,
(data[size - 1] % 3) >= 2);
}
void UtfHelperIsValidUTF8(const uint8_t* data, size_t size)
{
if (size == 0) {
return;
}
const std::vector<uint8_t> utfDataFourBitVaild = {BIT_MASK_4, BIT_MASK_1 + 0x10, BIT_MASK_1, BIT_MASK_1};
std::vector<uint8_t> tmpUtfData;
size_t vecLen = (data[size - 1] % 4 == 0 ? 1 : data[size - 1] % 4);
for (size_t i = 0; i < vecLen; ++i) {
tmpUtfData.push_back(utfDataFourBitVaild[i]);
}
common::utf_helper::IsValidUTF8(tmpUtfData);
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
OHOS::UtfHelperGetValueFromTwoHex(data, size);
OHOS::UtfHelperGetHexChar16(data, size);
OHOS::UtfHelperCombineTwoU16(data, size);
OHOS::UtfHelperUTF16Decode(data, size);
OHOS::UtfHelperDebuggerConvertRegionUtf16ToUtf8(data, size);
OHOS::UtfHelperConvertUtf8ToUtf16Pair(data, size);
OHOS::UtfHelperConvertUtf8ToUnicodeChar(data, size);
OHOS::UtfHelperConvertUtf16ToUtf8(data, size);
OHOS::UtfHelperIsValidUTF8(data, size);
return 0;
}