pcre2 / tests /tests_pcre2_compile_class_compile_eclass_nested.c
AryaWu's picture
Upload folder using huggingface_hub
864071c verified
#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>
#include <stdbool.h>
/* The wrapper is defined in the module under test. We declare it with a
void* for the first parameter to avoid needing eclass_context's definition. */
extern BOOL test_compile_eclass_nested(void *context,
BOOL negated,
uint32_t **pptr,
PCRE2_UCHAR **pcode,
eclass_op_info *pop_info,
PCRE2_SIZE *lengthptr);
static void assert_bits_all(uint8_t *bits, uint8_t value)
{
for (int i = 0; i < 32; i++)
{
TEST_ASSERT_EQUAL_HEX8_MESSAGE(value, bits[i], "Bitset value mismatch");
}
}
static void assert_single_op(const eclass_op_info *info, int expected_op)
{
TEST_ASSERT_EQUAL_UINT_MESSAGE(1, info->length, "Expected single opcode length");
TEST_ASSERT_EQUAL_INT_MESSAGE(expected_op, info->op_single_type, "op_single_type mismatch");
TEST_ASSERT_NOT_NULL(info->code_start);
TEST_ASSERT_EQUAL_INT8_MESSAGE((int8_t)expected_op, (int8_t)info->code_start[0], "Emitted opcode mismatch");
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
/* [] => NONE */
void test_compile_eclass_nested_empty_returns_none(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[16] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_NONE);
assert_bits_all(info.bits.classbits, 0x00);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* [^] (via META_CLASS_NOT around a nested class with empty) => ANY */
void test_compile_eclass_nested_empty_with_outer_not_returns_any(void)
{
uint32_t tokens[] = {
(META_CLASS_NOT | CLASS_IS_ECLASS),
META_CLASS_EMPTY,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[16] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_ANY);
assert_bits_all(info.bits.classbits, 0xFF);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* ![] (META_ECLASS_NOT unary) => ANY */
void test_compile_eclass_nested_unary_not_operator(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_ECLASS_NOT,
META_CLASS_EMPTY,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[16] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_ANY);
assert_bits_all(info.bits.classbits, 0xFF);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* [] && [^] => NONE */
void test_compile_eclass_nested_binary_and_folding(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY,
META_ECLASS_AND,
META_CLASS_EMPTY_NOT,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[32] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_NONE);
assert_bits_all(info.bits.classbits, 0x00);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* [] || [^] => ANY */
void test_compile_eclass_nested_binary_or_folding(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY,
META_ECLASS_OR,
META_CLASS_EMPTY_NOT,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[32] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_ANY);
assert_bits_all(info.bits.classbits, 0xFF);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* [^] -- [^] => ANY && !ANY => NONE */
void test_compile_eclass_nested_binary_sub_folding(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY_NOT,
META_ECLASS_SUB,
META_CLASS_EMPTY_NOT,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[32] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_NONE);
assert_bits_all(info.bits.classbits, 0x00);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* [^] XOR [^] => NONE */
void test_compile_eclass_nested_binary_xor_folding(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY_NOT,
META_ECLASS_XOR,
META_CLASS_EMPTY_NOT,
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[32] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_NONE);
assert_bits_all(info.bits.classbits, 0x00);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* Nested class inside: ([^]) && ([]) => NONE */
void test_compile_eclass_nested_with_nested_operand(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
/* Nested start */
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY_NOT, /* inner => ANY */
META_CLASS_END, /* end inner */
META_ECLASS_AND,
META_CLASS_EMPTY, /* outer RHS => NONE */
META_CLASS_END /* end outer */
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[32] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, NULL);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
assert_single_op(&info, ECL_NONE);
assert_bits_all(info.bits.classbits, 0x00);
TEST_ASSERT_EQUAL_PTR(info.code_start + info.length, code);
}
/* lengthptr counting for a single operand: should be 1 */
void test_compile_eclass_nested_lengthptr_single_operand_counts_one(void)
{
uint32_t tokens[] = {
(META_CLASS | CLASS_IS_ECLASS),
META_CLASS_EMPTY_NOT, /* ANY */
META_CLASS_END
};
uint32_t *ptr = tokens;
PCRE2_UCHAR codebuf[16] = {0};
PCRE2_UCHAR *code = codebuf;
eclass_op_info info;
PCRE2_SIZE length = 0;
BOOL ok = test_compile_eclass_nested(NULL, FALSE, &ptr, &code, &info, &length);
TEST_ASSERT_TRUE(ok);
TEST_ASSERT_EQUAL_UINT32(META_CLASS_END, *ptr);
TEST_ASSERT_EQUAL_UINT(1, length);
/* In lengthptr mode, code pointer should not advance. */
TEST_ASSERT_EQUAL_PTR(codebuf, code);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_compile_eclass_nested_empty_returns_none);
RUN_TEST(test_compile_eclass_nested_empty_with_outer_not_returns_any);
RUN_TEST(test_compile_eclass_nested_unary_not_operator);
RUN_TEST(test_compile_eclass_nested_binary_and_folding);
RUN_TEST(test_compile_eclass_nested_binary_or_folding);
RUN_TEST(test_compile_eclass_nested_binary_sub_folding);
RUN_TEST(test_compile_eclass_nested_binary_xor_folding);
RUN_TEST(test_compile_eclass_nested_with_nested_operand);
RUN_TEST(test_compile_eclass_nested_lengthptr_single_operand_counts_one);
return UNITY_END();
}