| #include "unity/unity.h" |
| #define PCRE2_CODE_UNIT_WIDTH 8 |
| #include "pcre2.h" |
|
|
| #include <stdint.h> |
| #include <string.h> |
| #include <stdlib.h> |
|
|
| |
| #include "pcre2_compile.h" |
|
|
| |
| extern void test_add_to_class(uint32_t options, uint32_t xoptions, compile_block *cb, |
| uint32_t start, uint32_t end); |
|
|
| |
| static compile_block g_cb; |
| static uint8_t g_fcc[256]; |
|
|
| static int bit_is_set(const uint8_t *bits, uint32_t c) |
| { |
| return (bits[c >> 3] & (uint8_t)(1u << (c & 7))) != 0; |
| } |
|
|
| static void init_fcc_ascii_flipcase(uint8_t *fcc) |
| { |
| for (int i = 0; i < 256; i++) { |
| if (i >= 'a' && i <= 'z') fcc[i] = (uint8_t)(i - ('a' - 'A')); |
| else if (i >= 'A' && i <= 'Z') fcc[i] = (uint8_t)(i + ('a' - 'A')); |
| else fcc[i] = (uint8_t)i; |
| } |
| } |
|
|
| void setUp(void) { |
| memset(&g_cb, 0, sizeof(g_cb)); |
| memset(g_cb.classbits.classbits, 0, 32); |
| init_fcc_ascii_flipcase(g_fcc); |
| g_cb.fcc = g_fcc; |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
|
|
| void test_add_to_class_func_single_byte_sets_bit(void) |
| { |
| |
| test_add_to_class(0, 0, &g_cb, (uint32_t)'A', (uint32_t)'A'); |
|
|
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'A')); |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 'A' - 1)); |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 'A' + 1)); |
| } |
|
|
| void test_add_to_class_func_range_sets_bits_and_middle_bytes_ff(void) |
| { |
| |
| memset(g_cb.classbits.classbits, 0, 32); |
| test_add_to_class(0, 0, &g_cb, 10u, 250u); |
|
|
| |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 9)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 10)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 127)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 128)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 250)); |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 251)); |
|
|
| |
| for (int i = 2; i <= 30; i++) { |
| TEST_ASSERT_EQUAL_HEX8(0xFF, g_cb.classbits.classbits[i]); |
| } |
| } |
|
|
| void test_add_to_class_func_caseless_adds_folded_counterparts_lowercase_input(void) |
| { |
| memset(g_cb.classbits.classbits, 0, 32); |
| test_add_to_class(PCRE2_CASELESS, 0, &g_cb, (uint32_t)'a', (uint32_t)'c'); |
|
|
| |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'a')); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'b')); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'c')); |
| |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'A')); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'B')); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'C')); |
| |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 'd')); |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 'D')); |
| } |
|
|
| void test_add_to_class_func_caseless_adds_folded_counterparts_uppercase_input(void) |
| { |
| memset(g_cb.classbits.classbits, 0, 32); |
| test_add_to_class(PCRE2_CASELESS, 0, &g_cb, (uint32_t)'X', (uint32_t)'X'); |
|
|
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'X')); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 'x')); |
| } |
|
|
| void test_add_to_class_func_end_over_255_is_clamped(void) |
| { |
| memset(g_cb.classbits.classbits, 0, 32); |
| test_add_to_class(0, 0, &g_cb, 200u, 300u); |
|
|
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 199)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 200)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 255)); |
| |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 0)); |
| } |
|
|
| void test_add_to_class_func_start_over_255_is_noop(void) |
| { |
| memset(g_cb.classbits.classbits, 0xAA, 32); |
| uint8_t before[32]; |
| memcpy(before, g_cb.classbits.classbits, 32); |
|
|
| test_add_to_class(0, 0, &g_cb, 300u, 400u); |
|
|
| TEST_ASSERT_EQUAL_UINT8_ARRAY(before, g_cb.classbits.classbits, 32); |
| } |
|
|
| void test_add_to_class_func_full_range_sets_all_bits(void) |
| { |
| memset(g_cb.classbits.classbits, 0, 32); |
| test_add_to_class(0, 0, &g_cb, 0u, 255u); |
|
|
| for (int i = 0; i < 32; i++) { |
| TEST_ASSERT_EQUAL_HEX8(0xFF, g_cb.classbits.classbits[i]); |
| } |
| } |
|
|
| void test_add_to_class_func_small_partial_boundaries(void) |
| { |
| memset(g_cb.classbits.classbits, 0, 32); |
| test_add_to_class(0, 0, &g_cb, 7u, 9u); |
|
|
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 6)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 7)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 8)); |
| TEST_ASSERT_TRUE(bit_is_set(g_cb.classbits.classbits, 9)); |
| TEST_ASSERT_FALSE(bit_is_set(g_cb.classbits.classbits, 10)); |
| } |
|
|
| int main(void) |
| { |
| UNITY_BEGIN(); |
| RUN_TEST(test_add_to_class_func_single_byte_sets_bit); |
| RUN_TEST(test_add_to_class_func_range_sets_bits_and_middle_bytes_ff); |
| RUN_TEST(test_add_to_class_func_caseless_adds_folded_counterparts_lowercase_input); |
| RUN_TEST(test_add_to_class_func_caseless_adds_folded_counterparts_uppercase_input); |
| RUN_TEST(test_add_to_class_func_end_over_255_is_clamped); |
| RUN_TEST(test_add_to_class_func_start_over_255_is_noop); |
| RUN_TEST(test_add_to_class_func_full_range_sets_all_bits); |
| RUN_TEST(test_add_to_class_func_small_partial_boundaries); |
| return UNITY_END(); |
| } |