/* * 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, // 10: val in [0x0, 0x9], convert to ['0', '9'] 'a' + data[size - 1] % 6); // 6:val in ['a', 'f'], convert to ['a', 'f'] } void UtfHelperGetHexChar16(const uint8_t* data, size_t size) { if (size == 0) { return; } GetHexChar16(data[size - 1] % 0xff); // 0xff: Maximum value of uint8 } void UtfHelperCombineTwoU16(const uint8_t* data, size_t size) { if (size == 0) { return; } CombineTwoU16(data[size - 1] % 0xff, (size / 2) % 0xff); // 2:half of the size,0xff: Maximum value of uint8 } 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; // 8:length of u16 size_t utf8Len = 100; // 100:buff len size_t start = 0; bool modify = ((data[size - 1] % 2 == 0) ? true : false); // 2:Check size is an even number uint16_t utf16Value[8] = { 0x00, // 0 or 2 (special case for \u0000 ==> C080 - 1100'0000 1000'0000) 0x7F, // 1(0x00, 0x7F] 0x7FF, // 2 [0x80, 0x7FF] 0x800, // 3 [0x800, 0xD7FF] 0xD800, // 3 [0xD800, 0xDFFF] 0xFFFF, // 3 [0xE000, 0xFFFF] 0xD800, 0xDFFF}; // 4 [0x10000, 0x10FFFF] 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); // 2:Check size is even number uint8_t utf8Value2[1] = {UTF8_1B_MAX}; // 1: array len const uint8_t *utf8ValuePtr2 = utf8Value2; ConvertUtf8ToUtf16Pair(utf8ValuePtr1, (data[size - 1] % 2) == 1); // 2:Check size is even number } void UtfHelperConvertUtf8ToUnicodeChar(const uint8_t* data, size_t size) { if (size == 0) { return; } uint8_t utf8Value11[4] = {0xF4, 0x80, 0x80, 0x40}; // invalid const uint8_t *utf8ValuePtr11 = utf8Value11; ConvertUtf8ToUnicodeChar(utf8ValuePtr11, static_cast(data[size - 1] % 4)); // 4: lenth of array } void UtfHelperConvertUtf16ToUtf8(const uint8_t* data, size_t size) { if (size == 0) { return; } uint16_t utf16Data0[5] = {0x0, 0x7f, 0x7ff, 0xd800, 0xdfff}; // invalid uint16_t utf16Data1[2] = {LO_SURROGATE_MIN + 1, LO_SURROGATE_MAX - 1}; ConvertUtf16ToUtf8(utf16Data0[data[size - 1] % 5], // 5:length of utf16Data0 utf16Data1[data[size - 1] % 2], (data[size - 1] % 2) == 1, // 2:Check size is even number (data[size - 1] % 3) >= 2); // 3:Get Remainder } void UtfHelperIsValidUTF8(const uint8_t* data, size_t size) { if (size == 0) { return; } const std::vector utfDataFourBitVaild = {BIT_MASK_4, BIT_MASK_1 + 0x10, BIT_MASK_1, BIT_MASK_1}; std::vector tmpUtfData; size_t vecLen = (data[size - 1] % 4 == 0 ? 1 : data[size - 1] % 4); // 4:number of utfDataFourBitVaild array for (size_t i = 0; i < vecLen; ++i) { tmpUtfData.push_back(utfDataFourBitVaild[i]); } common::utf_helper::IsValidUTF8(tmpUtfData); } } // Fuzzer entry point. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Run your code on data. 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; }