| #include "unity/unity.h" |
| #define PCRE2_CODE_UNIT_WIDTH 8 |
| #include "pcre2.h" |
|
|
| #include <stdlib.h> |
| #include <string.h> |
|
|
| |
| static pcre2_code* compile_pat(const char* pat) |
| { |
| int errorcode = 0; |
| PCRE2_SIZE erroroffset = 0; |
| pcre2_code* code = pcre2_compile( |
| (PCRE2_SPTR)pat, |
| PCRE2_ZERO_TERMINATED, |
| 0, |
| &errorcode, |
| &erroroffset, |
| NULL); |
|
|
| if (code == NULL) { |
| char msg[256]; |
| snprintf(msg, sizeof(msg), "pcre2_compile failed: error %d at offset %zu for pattern '%s'", |
| errorcode, (size_t)erroroffset, pat); |
| TEST_FAIL_MESSAGE(msg); |
| } |
| return code; |
| } |
|
|
| |
| static int match_rc(pcre2_code* code, const char* subject) |
| { |
| pcre2_match_data* mdata = pcre2_match_data_create_from_pattern(code, NULL); |
| TEST_ASSERT_NOT_NULL_MESSAGE(mdata, "pcre2_match_data_create_from_pattern returned NULL"); |
| int rc = pcre2_match( |
| code, |
| (PCRE2_SPTR)subject, |
| (PCRE2_SIZE)strlen(subject), |
| 0, |
| 0, |
| mdata, |
| NULL); |
| pcre2_match_data_free(mdata); |
| return rc; |
| } |
|
|
| void setUp(void) { |
| |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| void test_pcre2_code_free_null_ok(void) |
| { |
| pcre2_code_free(NULL); |
| TEST_PASS(); |
| } |
|
|
| |
| void test_pcre2_code_free_basic_code(void) |
| { |
| pcre2_code* code = compile_pat("a+"); |
| int rc = match_rc(code, "aaa"); |
| TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(0, rc, "Expected a successful match before free"); |
| pcre2_code_free(code); |
| |
| } |
|
|
| |
| void test_pcre2_code_free_shared_tables_refcount_two(void) |
| { |
| |
| pcre2_code* base = compile_pat("abc"); |
|
|
| |
| pcre2_code* codeA = pcre2_code_copy_with_tables(base); |
| TEST_ASSERT_NOT_NULL_MESSAGE(codeA, "pcre2_code_copy_with_tables returned NULL"); |
|
|
| |
| pcre2_code* codeB = pcre2_code_copy(codeA); |
| TEST_ASSERT_NOT_NULL_MESSAGE(codeB, "pcre2_code_copy returned NULL"); |
|
|
| |
| pcre2_code_free(codeA); |
|
|
| |
| int rc = match_rc(codeB, "xyzabcxyz"); |
| TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(0, rc, "Expected successful match with remaining sharer after freeing another"); |
|
|
| |
| pcre2_code_free(codeB); |
| pcre2_code_free(base); |
| } |
|
|
| |
| void test_pcre2_code_free_shared_tables_refcount_chain(void) |
| { |
| pcre2_code* base = compile_pat("h.*o"); |
|
|
| pcre2_code* codeA = pcre2_code_copy_with_tables(base); |
| TEST_ASSERT_NOT_NULL_MESSAGE(codeA, "pcre2_code_copy_with_tables returned NULL"); |
|
|
| pcre2_code* codeB = pcre2_code_copy(codeA); |
| TEST_ASSERT_NOT_NULL_MESSAGE(codeB, "pcre2_code_copy returned NULL (B)"); |
|
|
| pcre2_code* codeC = pcre2_code_copy(codeA); |
| TEST_ASSERT_NOT_NULL_MESSAGE(codeC, "pcre2_code_copy returned NULL (C)"); |
|
|
| |
| pcre2_code_free(codeA); |
| pcre2_code_free(codeB); |
|
|
| |
| int rc = match_rc(codeC, "hello"); |
| TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(0, rc, "Expected successful match with last remaining sharer"); |
|
|
| |
| pcre2_code_free(codeC); |
| pcre2_code_free(base); |
| } |
|
|
| int main(void) |
| { |
| UNITY_BEGIN(); |
|
|
| RUN_TEST(test_pcre2_code_free_null_ok); |
| RUN_TEST(test_pcre2_code_free_basic_code); |
| RUN_TEST(test_pcre2_code_free_shared_tables_refcount_two); |
| RUN_TEST(test_pcre2_code_free_shared_tables_refcount_chain); |
|
|
| return UNITY_END(); |
| } |