brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 15892bd Raw
140 lines · cpp
1//===-- Unittests for mbrlen ----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "hdr/errno_macros.h"10#include "hdr/types/wchar_t.h"11#include "src/__support/wchar/mbstate.h"12#include "src/string/memset.h"13#include "src/wchar/mbrlen.h"14#include "test/UnitTest/ErrnoCheckingTest.h"15#include "test/UnitTest/Test.h"16 17using LlvmLibcMBRLenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;18 19TEST_F(LlvmLibcMBRLenTest, OneByte) {20  const char *ch = "A";21  mbstate_t mb;22  LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));23  size_t n = LIBC_NAMESPACE::mbrlen(ch, 1, &mb);24  ASSERT_ERRNO_SUCCESS();25  ASSERT_EQ(n, static_cast<size_t>(1));26 27  // Should fail since we have not read enough28  n = LIBC_NAMESPACE::mbrlen(ch, 0, &mb);29  ASSERT_ERRNO_SUCCESS();30  ASSERT_EQ(n, static_cast<size_t>(-2));31}32 33TEST_F(LlvmLibcMBRLenTest, TwoByte) {34  const char ch[2] = {static_cast<char>(0xC2),35                      static_cast<char>(0x8E)}; // Ž car symbol36  mbstate_t mb;37  LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));38  size_t n = LIBC_NAMESPACE::mbrlen(ch, 4, nullptr);39  ASSERT_ERRNO_SUCCESS();40  ASSERT_EQ(static_cast<int>(n), 2);41 42  // Should fail since we have not read enough43  n = LIBC_NAMESPACE::mbrlen(ch, 1, &mb);44  ASSERT_EQ(static_cast<int>(n), -2);45  ASSERT_ERRNO_SUCCESS();46  // Should pass after trying to read next byte47  n = LIBC_NAMESPACE::mbrlen(ch + 1, 1, &mb);48  ASSERT_EQ(static_cast<int>(n), 1);49  ASSERT_ERRNO_SUCCESS();50}51 52TEST_F(LlvmLibcMBRLenTest, ThreeByte) {53  const char ch[3] = {static_cast<char>(0xE2), static_cast<char>(0x88),54                      static_cast<char>(0x91)}; // ∑ sigma symbol55  mbstate_t mb;56  LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));57  size_t n = LIBC_NAMESPACE::mbrlen(ch, 3, &mb);58  ASSERT_EQ(static_cast<int>(n), 3);59  ASSERT_ERRNO_SUCCESS();60 61  // Should fail since we have not read enough62  n = LIBC_NAMESPACE::mbrlen(ch, 2, &mb);63  ASSERT_EQ(static_cast<int>(n), -2);64  ASSERT_ERRNO_SUCCESS();65}66 67TEST_F(LlvmLibcMBRLenTest, FourByte) {68  const char ch[4] = {static_cast<char>(0xF0), static_cast<char>(0x9F),69                      static_cast<char>(0xA4),70                      static_cast<char>(0xA1)}; // 🤡 clown emoji71  mbstate_t mb;72  LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));73  size_t n = LIBC_NAMESPACE::mbrlen(ch, 4, &mb);74  ASSERT_EQ(static_cast<int>(n), 4);75  ASSERT_ERRNO_SUCCESS();76 77  // Should fail since we have not read enough78  n = LIBC_NAMESPACE::mbrlen(ch, 2, &mb);79  ASSERT_EQ(static_cast<int>(n), -2);80  ASSERT_ERRNO_SUCCESS();81 82  // Should fail since we have not read enough83  n = LIBC_NAMESPACE::mbrlen(ch + 2, 1, &mb);84  ASSERT_EQ(static_cast<int>(n), -2);85  ASSERT_ERRNO_SUCCESS();86 87  // Should pass after reading final byte88  n = LIBC_NAMESPACE::mbrlen(ch + 3, 5, &mb);89  ASSERT_EQ(static_cast<int>(n), 1);90  ASSERT_ERRNO_SUCCESS();91}92 93TEST_F(LlvmLibcMBRLenTest, InvalidByte) {94  const char ch[1] = {static_cast<char>(0x80)};95  size_t n = LIBC_NAMESPACE::mbrlen(ch, 1, nullptr);96  ASSERT_EQ(static_cast<int>(n), -1);97  ASSERT_ERRNO_EQ(EILSEQ);98}99 100TEST_F(LlvmLibcMBRLenTest, InvalidMultiByte) {101  const char ch[4] = {static_cast<char>(0x80), static_cast<char>(0x00),102                      static_cast<char>(0x80),103                      static_cast<char>(0x00)}; // invalid sequence of bytes104  mbstate_t mb;105  LIBC_NAMESPACE::memset(&mb, 0, sizeof(mbstate_t));106  // Trying to push all 4 should error107  size_t n = LIBC_NAMESPACE::mbrlen(ch, 4, &mb);108  ASSERT_EQ(static_cast<int>(n), -1);109  ASSERT_ERRNO_EQ(EILSEQ);110 111  // Trying to push the second and third should correspond to null wc112  n = LIBC_NAMESPACE::mbrlen(ch + 1, 2, &mb);113  ASSERT_EQ(static_cast<int>(n), 0);114  ASSERT_ERRNO_SUCCESS();115}116 117TEST_F(LlvmLibcMBRLenTest, NullString) {118  // reading on nullptr should return 0119  size_t n = LIBC_NAMESPACE::mbrlen(nullptr, 2, nullptr);120  ASSERT_EQ(static_cast<int>(n), 0);121  ASSERT_ERRNO_SUCCESS();122  // reading a null terminator should return 0123  const char *ch = "\0";124  n = LIBC_NAMESPACE::mbrlen(ch, 1, nullptr);125  ASSERT_EQ(static_cast<int>(n), 0);126}127 128TEST_F(LlvmLibcMBRLenTest, InvalidMBState) {129  const char ch[4] = {static_cast<char>(0xC2), static_cast<char>(0x8E),130                      static_cast<char>(0xC7), static_cast<char>(0x8C)};131  mbstate_t *mb;132  LIBC_NAMESPACE::internal::mbstate inv;133  inv.total_bytes = 6;134  mb = reinterpret_cast<mbstate_t *>(&inv);135  // invalid mbstate should error136  size_t n = LIBC_NAMESPACE::mbrlen(ch, 2, mb);137  ASSERT_EQ(static_cast<int>(n), -1);138  ASSERT_ERRNO_EQ(EINVAL);139}140