| #include "unity/unity.h" |
| #define PCRE2_CODE_UNIT_WIDTH 8 |
| #include "pcre2.h" |
|
|
| |
| #include "pcre2_compile.h" |
|
|
| #include <string.h> |
| #include <stdint.h> |
| #include <stdlib.h> |
|
|
| |
| |
| extern BOOL test_compile_class_operand(void *context, BOOL negated, |
| uint32_t **pptr, PCRE2_UCHAR **pcode, |
| eclass_op_info *pop_info, |
| PCRE2_SIZE *lengthptr); |
|
|
| static void assert_bits_all_ones(const eclass_op_info *info) { |
| for (int i = 0; i < 8; i++) { |
| TEST_ASSERT_EQUAL_HEX32(0xFFFFFFFFu, info->bits.classwords[i]); |
| } |
| } |
| static void assert_bits_all_zeros(const eclass_op_info *info) { |
| for (int i = 0; i < 8; i++) { |
| TEST_ASSERT_EQUAL_HEX32(0x00000000u, info->bits.classwords[i]); |
| } |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| static void run_empty_case(uint32_t token, BOOL negated, |
| uint8_t expected_opcode, BOOL expect_all_ones_bits, |
| BOOL use_length_only_mode) |
| { |
| uint32_t tokens[3]; |
| tokens[0] = token; |
| tokens[1] = META_CLASS_END; |
| tokens[2] = META_END; |
|
|
| uint32_t *ptr = tokens; |
|
|
| PCRE2_UCHAR codebuf[16]; |
| memset(codebuf, 0, sizeof(codebuf)); |
| PCRE2_UCHAR *codep = codebuf; |
|
|
| eclass_op_info opinfo; |
| memset(&opinfo, 0xCC, sizeof(opinfo)); |
|
|
| PCRE2_SIZE len = 0; |
| PCRE2_SIZE *lengthptr = use_length_only_mode ? &len : NULL; |
|
|
| BOOL ok = test_compile_class_operand(NULL , |
| negated, &ptr, &codep, &opinfo, lengthptr); |
| TEST_ASSERT_TRUE_MESSAGE(ok, "compile_class_operand returned FALSE"); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(tokens + 1, ptr); |
|
|
| if (use_length_only_mode) { |
| |
| TEST_ASSERT_EQUAL_PTR(codebuf, codep); |
| TEST_ASSERT_EQUAL_size_t(1, len); |
| |
| TEST_ASSERT_EQUAL_HEX8(expected_opcode, codebuf[0]); |
| TEST_ASSERT_NULL(opinfo.code_start); |
| } else { |
| TEST_ASSERT_EQUAL_HEX8(expected_opcode, codebuf[0]); |
| TEST_ASSERT_EQUAL_PTR(codebuf + 1, codep); |
| TEST_ASSERT_EQUAL_PTR(codebuf, opinfo.code_start); |
| } |
|
|
| TEST_ASSERT_EQUAL_UINT(1, opinfo.length); |
| TEST_ASSERT_EQUAL_HEX8(expected_opcode, opinfo.op_single_type); |
|
|
| if (expect_all_ones_bits) { |
| assert_bits_all_ones(&opinfo); |
| } else { |
| assert_bits_all_zeros(&opinfo); |
| } |
| } |
|
|
| void test_compile_class_operand_EMPTY_negated_false(void) { |
| |
| run_empty_case(META_CLASS_EMPTY, FALSE, ECL_NONE, FALSE, FALSE); |
| } |
|
|
| void test_compile_class_operand_EMPTY_negated_true(void) { |
| |
| run_empty_case(META_CLASS_EMPTY, TRUE, ECL_ANY, TRUE, FALSE); |
| } |
|
|
| void test_compile_class_operand_EMPTY_NOT_negated_false(void) { |
| |
| run_empty_case(META_CLASS_EMPTY_NOT, FALSE, ECL_ANY, TRUE, FALSE); |
| } |
|
|
| void test_compile_class_operand_EMPTY_NOT_negated_true(void) { |
| |
| run_empty_case(META_CLASS_EMPTY_NOT, TRUE, ECL_NONE, FALSE, FALSE); |
| } |
|
|
| void test_compile_class_operand_length_only_mode(void) { |
| |
| run_empty_case(META_CLASS_EMPTY_NOT, FALSE, ECL_ANY, TRUE, TRUE); |
| } |
|
|
| |
| static void run_nested_empty_case(uint32_t inner_token, BOOL outer_negated, |
| uint8_t expected_opcode, BOOL expect_all_ones_bits, |
| BOOL use_length_only_mode) |
| { |
| uint32_t tokens[4]; |
| tokens[0] = META_CLASS | CLASS_IS_ECLASS; |
| tokens[1] = inner_token; |
| tokens[2] = META_CLASS_END; |
| tokens[3] = META_END; |
|
|
| uint32_t *ptr = tokens; |
|
|
| PCRE2_UCHAR codebuf[16]; |
| memset(codebuf, 0, sizeof(codebuf)); |
| PCRE2_UCHAR *codep = codebuf; |
|
|
| eclass_op_info opinfo; |
| memset(&opinfo, 0xCC, sizeof(opinfo)); |
|
|
| PCRE2_SIZE len = 0; |
| PCRE2_SIZE *lengthptr = use_length_only_mode ? &len : NULL; |
|
|
| BOOL ok = test_compile_class_operand(NULL , |
| outer_negated, &ptr, &codep, &opinfo, lengthptr); |
| TEST_ASSERT_TRUE(ok); |
|
|
| |
| TEST_ASSERT_EQUAL_PTR(tokens + 3, ptr); |
|
|
| if (use_length_only_mode) { |
| TEST_ASSERT_EQUAL_PTR(codebuf, codep); |
| TEST_ASSERT_EQUAL_size_t(1, len); |
| TEST_ASSERT_EQUAL_HEX8(expected_opcode, codebuf[0]); |
| TEST_ASSERT_NULL(opinfo.code_start); |
| } else { |
| TEST_ASSERT_EQUAL_HEX8(expected_opcode, codebuf[0]); |
| TEST_ASSERT_EQUAL_PTR(codebuf + 1, codep); |
| TEST_ASSERT_EQUAL_PTR(codebuf, opinfo.code_start); |
| } |
|
|
| TEST_ASSERT_EQUAL_UINT(1, opinfo.length); |
| TEST_ASSERT_EQUAL_HEX8(expected_opcode, opinfo.op_single_type); |
|
|
| if (expect_all_ones_bits) { |
| assert_bits_all_ones(&opinfo); |
| } else { |
| assert_bits_all_zeros(&opinfo); |
| } |
| } |
|
|
| void test_compile_class_operand_nested_EMPTY_not_negated(void) { |
| |
| run_nested_empty_case(META_CLASS_EMPTY, FALSE, ECL_NONE, FALSE, FALSE); |
| } |
|
|
| void test_compile_class_operand_nested_EMPTY_negated(void) { |
| |
| run_nested_empty_case(META_CLASS_EMPTY, TRUE, ECL_ANY, TRUE, FALSE); |
| } |
|
|
| void test_compile_class_operand_nested_EMPTY_length_only_mode(void) { |
| |
| run_nested_empty_case(META_CLASS_EMPTY_NOT, FALSE, ECL_ANY, TRUE, TRUE); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
|
|
| RUN_TEST(test_compile_class_operand_EMPTY_negated_false); |
| RUN_TEST(test_compile_class_operand_EMPTY_negated_true); |
| RUN_TEST(test_compile_class_operand_EMPTY_NOT_negated_false); |
| RUN_TEST(test_compile_class_operand_EMPTY_NOT_negated_true); |
| RUN_TEST(test_compile_class_operand_length_only_mode); |
|
|
| RUN_TEST(test_compile_class_operand_nested_EMPTY_not_negated); |
| RUN_TEST(test_compile_class_operand_nested_EMPTY_negated); |
| RUN_TEST(test_compile_class_operand_nested_EMPTY_length_only_mode); |
|
|
| return UNITY_END(); |
| } |