| #include "unity/unity.h" |
| #define PCRE2_CODE_UNIT_WIDTH 8 |
| #include "pcre2.h" |
| #include "pcre2_compile.h" |
|
|
| #include <stdlib.h> |
| #include <string.h> |
|
|
| |
| extern int test_parse_regex(PCRE2_SPTR ptr, uint32_t options, uint32_t xoptions, BOOL *has_lookbehind, compile_block *cb); |
|
|
| static pcre2_compile_context *g_cctx = NULL; |
|
|
| |
| static void init_cb(compile_block *cb, |
| PCRE2_SPTR pattern, |
| size_t patlen, |
| uint32_t workspace_units, |
| uint32_t parsed_units) |
| { |
| memset(cb, 0, sizeof(*cb)); |
| cb->start_pattern = pattern; |
| cb->end_pattern = pattern + patlen; |
|
|
| |
| cb->cx = g_cctx; |
|
|
| |
| cb->start_workspace = (PCRE2_UCHAR *)calloc(workspace_units, sizeof(PCRE2_UCHAR)); |
| cb->workspace_size = workspace_units; |
|
|
| |
| cb->parsed_pattern = (uint32_t *)calloc(parsed_units, sizeof(uint32_t)); |
| cb->parsed_pattern_end = cb->parsed_pattern + parsed_units; |
|
|
| |
| } |
|
|
| static void free_cb(compile_block *cb) |
| { |
| if (cb->start_workspace) free(cb->start_workspace); |
| if (cb->parsed_pattern) free(cb->parsed_pattern); |
| memset(cb, 0, sizeof(*cb)); |
| } |
|
|
| void setUp(void) { |
| |
| g_cctx = pcre2_compile_context_create(NULL); |
| |
| } |
|
|
| void tearDown(void) { |
| if (g_cctx) { |
| pcre2_compile_context_free(g_cctx); |
| g_cctx = NULL; |
| } |
| } |
|
|
| |
| void test_parse_regex_literal_basic(void) |
| { |
| const char *pat_cstr = "abc"; |
| PCRE2_SPTR pattern = (PCRE2_SPTR)(const unsigned char *)pat_cstr; |
| size_t patlen = strlen(pat_cstr); |
|
|
| compile_block cb; |
| init_cb(&cb, pattern, patlen, 1024, 64); |
|
|
| BOOL has_lb = FALSE; |
| uint32_t options = PCRE2_LITERAL; |
| uint32_t xoptions = 0; |
|
|
| int rc = test_parse_regex(pattern, options, xoptions, &has_lb, &cb); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
| TEST_ASSERT_FALSE(has_lb); |
|
|
| |
| TEST_ASSERT_NOT_NULL(cb.parsed_pattern); |
| TEST_ASSERT_EQUAL_UINT32('a', cb.parsed_pattern[0]); |
| TEST_ASSERT_EQUAL_UINT32('b', cb.parsed_pattern[1]); |
| TEST_ASSERT_EQUAL_UINT32('c', cb.parsed_pattern[2]); |
|
|
| free_cb(&cb); |
| } |
|
|
| |
| void test_parse_regex_lookbehind_flag(void) |
| { |
| const char *pat_cstr = "(?<=a)b"; |
| PCRE2_SPTR pattern = (PCRE2_SPTR)(const unsigned char *)pat_cstr; |
| size_t patlen = strlen(pat_cstr); |
|
|
| compile_block cb; |
| init_cb(&cb, pattern, patlen, 2048, 128); |
|
|
| BOOL has_lb = FALSE; |
| uint32_t options = 0; |
| uint32_t xoptions = 0; |
|
|
| int rc = test_parse_regex(pattern, options, xoptions, &has_lb, &cb); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
| TEST_ASSERT_TRUE(has_lb); |
| |
| TEST_ASSERT_EQUAL_UINT32(0, cb.bracount); |
|
|
| free_cb(&cb); |
| } |
|
|
| |
| void test_parse_regex_unmatched_paren_error_offset(void) |
| { |
| const char *pat_cstr = "("; |
| PCRE2_SPTR pattern = (PCRE2_SPTR)(const unsigned char *)pat_cstr; |
| size_t patlen = strlen(pat_cstr); |
|
|
| compile_block cb; |
| init_cb(&cb, pattern, patlen, 512, 32); |
|
|
| BOOL has_lb = FALSE; |
| uint32_t options = 0; |
| uint32_t xoptions = 0; |
|
|
| int rc = test_parse_regex(pattern, options, xoptions, &has_lb, &cb); |
| TEST_ASSERT_NOT_EQUAL(0, rc); |
| |
| TEST_ASSERT_EQUAL_SIZE(1, cb.erroroffset); |
|
|
| free_cb(&cb); |
| } |
|
|
| |
| void test_parse_regex_trailing_backslash_error(void) |
| { |
| const char *pat_cstr = "\\"; |
| PCRE2_SPTR pattern = (PCRE2_SPTR)(const unsigned char *)pat_cstr; |
| size_t patlen = strlen(pat_cstr); |
|
|
| compile_block cb; |
| init_cb(&cb, pattern, patlen, 512, 32); |
|
|
| BOOL has_lb = FALSE; |
| uint32_t options = 0; |
| uint32_t xoptions = 0; |
|
|
| int rc = test_parse_regex(pattern, options, xoptions, &has_lb, &cb); |
| TEST_ASSERT_NOT_EQUAL(0, rc); |
| |
| TEST_ASSERT_EQUAL_SIZE(1, cb.erroroffset); |
|
|
| free_cb(&cb); |
| } |
|
|
| |
| void test_parse_regex_capturing_group_count(void) |
| { |
| const char *pat_cstr = "(a)"; |
| PCRE2_SPTR pattern = (PCRE2_SPTR)(const unsigned char *)pat_cstr; |
| size_t patlen = strlen(pat_cstr); |
|
|
| compile_block cb; |
| init_cb(&cb, pattern, patlen, 2048, 128); |
|
|
| BOOL has_lb = FALSE; |
| uint32_t options = 0; |
| uint32_t xoptions = 0; |
|
|
| int rc = test_parse_regex(pattern, options, xoptions, &has_lb, &cb); |
| TEST_ASSERT_EQUAL_INT(0, rc); |
| TEST_ASSERT_FALSE(has_lb); |
| TEST_ASSERT_EQUAL_UINT32(1, cb.bracount); |
|
|
| free_cb(&cb); |
| } |
|
|
| int main(void) |
| { |
| UNITY_BEGIN(); |
| RUN_TEST(test_parse_regex_literal_basic); |
| RUN_TEST(test_parse_regex_lookbehind_flag); |
| RUN_TEST(test_parse_regex_unmatched_paren_error_offset); |
| RUN_TEST(test_parse_regex_trailing_backslash_error); |
| RUN_TEST(test_parse_regex_capturing_group_count); |
| return UNITY_END(); |
| } |