| #include "unity/unity.h" |
| #define PCRE2_CODE_UNIT_WIDTH 8 |
| #include "pcre2.h" |
|
|
| #include <stdint.h> |
| #include <string.h> |
|
|
| |
| extern int test_read_number(PCRE2_SPTR *ptrptr, |
| PCRE2_SPTR ptrend, |
| int32_t allow_sign, |
| uint32_t max_value, |
| uint32_t max_error, |
| int *intptr, |
| int *errorcodeptr); |
|
|
| void setUp(void) { |
| |
| } |
| void tearDown(void) { |
| |
| } |
|
|
| |
| static void make_span(const char *s, PCRE2_SPTR *start, PCRE2_SPTR *end) { |
| *start = (const PCRE2_UCHAR *)s; |
| *end = (const PCRE2_UCHAR *)(s + strlen(s)); |
| } |
|
|
| |
| void test_read_number_basic(void) { |
| const char *s = "123abc"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = -1, err = -1; |
| PCRE2_SPTR p0 = p; |
|
|
| int rc = test_read_number(&p, e, -1, 100000, 9999, &out, &err); |
|
|
| TEST_ASSERT_TRUE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_INT(123, out); |
| |
| TEST_ASSERT_EQUAL_PTR((const void*)(p0 + 3), (const void*)p); |
| } |
|
|
| |
| void test_read_number_no_number_no_error(void) { |
| const char *s = "xyz"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| PCRE2_SPTR p0 = p; |
| int out = 0, err = 12345; |
|
|
| int rc = test_read_number(&p, e, -1, 100, 777, &out, &err); |
|
|
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_PTR((const void*)p0, (const void*)p); |
| } |
|
|
| |
| void test_read_number_sign_not_allowed(void) { |
| const char *s = "+3"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| PCRE2_SPTR p0 = p; |
| int out = 0, err = 0; |
|
|
| int rc = test_read_number(&p, e, -1, 100, 123, &out, &err); |
|
|
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_PTR((const void*)p0, (const void*)p); |
| } |
|
|
| |
| void test_read_number_positive_relative_valid(void) { |
| const char *s = "+2end"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
|
|
| int rc = test_read_number(&p, e, 3, 1000, 999, &out, &err); |
|
|
| TEST_ASSERT_TRUE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_INT(5, out); |
| |
| TEST_ASSERT_EQUAL_CHAR('e', *p); |
| } |
|
|
| |
| void test_read_number_negative_relative_valid(void) { |
| const char *s = "-2"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
|
|
| int rc = test_read_number(&p, e, 3, 1000, 999, &out, &err); |
|
|
| TEST_ASSERT_TRUE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_INT(2, out); |
| TEST_ASSERT_EQUAL_PTR((const void*)e, (const void*)p); |
| } |
|
|
| |
| void test_read_number_negative_relative_invalid(void) { |
| const char *s = "-4X"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
|
|
| int rc = test_read_number(&p, e, 3, 1000, 321, &out, &err); |
|
|
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_NOT_EQUAL(0, err); |
| |
| TEST_ASSERT_EQUAL_CHAR('X', *p); |
| } |
|
|
| |
| void test_read_number_signed_zero_is_invalid(void) { |
| |
| { |
| const char *s = "-0end"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
| int rc = test_read_number(&p, e, 5, 1000, 321, &out, &err); |
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_NOT_EQUAL(0, err); |
| |
| TEST_ASSERT_EQUAL_CHAR('e', *p); |
| } |
| |
| { |
| const char *s = "+0!"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
| int rc = test_read_number(&p, e, 7, 1000, 654, &out, &err); |
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_NOT_EQUAL(0, err); |
| TEST_ASSERT_EQUAL_CHAR('!', *p); |
| } |
| } |
|
|
| |
| void test_read_number_overflow_sets_error_and_skips_digits(void) { |
| const char *s = "123456a"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
| uint32_t max_error = 777; |
|
|
| int rc = test_read_number(&p, e, -1, 100, max_error, &out, &err); |
|
|
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_EQUAL_INT((int)max_error, err); |
| |
| TEST_ASSERT_EQUAL_CHAR('a', *p); |
| } |
|
|
| |
| void test_read_number_plus_without_digits_advances_pointer(void) { |
| const char *s = "+x"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| PCRE2_SPTR p0 = p; |
| int out = 0, err = 123; |
|
|
| int rc = test_read_number(&p, e, 0, 1000, 99, &out, &err); |
|
|
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| |
| TEST_ASSERT_EQUAL_PTR((const void*)(p0 + 1), (const void*)p); |
| TEST_ASSERT_EQUAL_CHAR('x', *p); |
| } |
|
|
| |
| |
| void test_read_number_plus_with_adjusted_maxvalue_guard(void) { |
| |
| { |
| const char *s = "+90."; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
| int rc = test_read_number(&p, e, 10, 100, 4242, &out, &err); |
| TEST_ASSERT_TRUE(rc); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_INT(100, out); |
| TEST_ASSERT_EQUAL_CHAR('.', *p); |
| } |
| |
| { |
| const char *s = "+91!"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
| uint32_t max_error = 5050; |
| int rc = test_read_number(&p, e, 10, 100, max_error, &out, &err); |
| TEST_ASSERT_FALSE(rc); |
| TEST_ASSERT_EQUAL_INT((int)max_error, err); |
| TEST_ASSERT_EQUAL_CHAR('!', *p); |
| } |
| } |
|
|
| |
| void test_read_number_consumes_to_ptrend(void) { |
| const char *s = "42"; |
| PCRE2_SPTR p, e; |
| make_span(s, &p, &e); |
| int out = 0, err = 0; |
| int rc = test_read_number(&p, e, -1, 1000, 123, &out, &err); |
| TEST_ASSERT_TRUE(rc); |
| TEST_ASSERT_EQUAL_INT(42, out); |
| TEST_ASSERT_EQUAL_INT(0, err); |
| TEST_ASSERT_EQUAL_PTR((const void*)e, (const void*)p); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_read_number_basic); |
| RUN_TEST(test_read_number_no_number_no_error); |
| RUN_TEST(test_read_number_sign_not_allowed); |
| RUN_TEST(test_read_number_positive_relative_valid); |
| RUN_TEST(test_read_number_negative_relative_valid); |
| RUN_TEST(test_read_number_negative_relative_invalid); |
| RUN_TEST(test_read_number_signed_zero_is_invalid); |
| RUN_TEST(test_read_number_overflow_sets_error_and_skips_digits); |
| RUN_TEST(test_read_number_plus_without_digits_advances_pointer); |
| RUN_TEST(test_read_number_plus_with_adjusted_maxvalue_guard); |
| RUN_TEST(test_read_number_consumes_to_ptrend); |
| return UNITY_END(); |
| } |