Skip to content

Commit 606e3c2

Browse files
committed
valgrind, cmake, and coverage improvements
1 parent ecf0fc4 commit 606e3c2

4 files changed

Lines changed: 74 additions & 9 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cmake_minimum_required(VERSION 3.11)
1+
cmake_minimum_required(VERSION 3.11...3.28)
22
project(c89stringutils VERSION 0.0.2 LANGUAGES C)
33

44
set(CMAKE_C_VISIBILITY_PRESET hidden)
@@ -56,12 +56,12 @@ configure_file(
5656
add_subdirectory("${PROJECT_NAME}")
5757

5858
include(CTest)
59-
option(BUILD_TESTING "Build the tests" ON)
6059
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
61-
option(C89STRINGUTILS_BUILD_TESTING "Build the tests" ON)
60+
set(C89STRINGUTILS_BUILD_TESTING_DEFAULT ON)
6261
else()
63-
option(C89STRINGUTILS_BUILD_TESTING "Build the tests" OFF)
62+
set(C89STRINGUTILS_BUILD_TESTING_DEFAULT OFF)
6463
endif()
64+
option(C89STRINGUTILS_BUILD_TESTING "Build the tests" ${C89STRINGUTILS_BUILD_TESTING_DEFAULT})
6565

6666
set(CDD_CHARSET "Unicode" CACHE STRING "Charset to use: Unicode or ANSI")
6767
set(CDD_THREADING "Multi-threaded" CACHE STRING "Threading: Multi-threaded or Single-threaded")

c89stringutils/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ set_property(TARGET "${LIBRARY_NAME}" PROPERTY SOVERSION "${${PROJECT_NAME}_VERS
4040

4141
set(installable_libs # "${EXEC_NAME}"
4242
"${LIBRARY_NAME}")
43-
if (TARGET "${DEPENDANT_LIBRARY}")
44-
list(APPEND installable_libs "${DEPENDANT_LIBRARY}")
43+
if (DEFINED DEPENDANT_LIBRARY)
44+
if (TARGET "${DEPENDANT_LIBRARY}")
45+
list(APPEND installable_libs "${DEPENDANT_LIBRARY}")
46+
endif ()
4547
endif ()
4648
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.19")
4749
list(APPEND installable_libs "${PROJECT_NAME}_compiler_flags")

c89stringutils/c89stringutils_string_extras.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ int strcasecmp(const char *s1, const char *s2) {
124124
char *strnstr(const char *buffer, const char *target, size_t bufferLength) {
125125
size_t targetLength;
126126
const char *start;
127+
size_t remaining;
127128
int rc;
128129
if (buffer == NULL || target == NULL) {
129130
LOG_DEBUG("buffer or target is NULL");
@@ -132,8 +133,9 @@ char *strnstr(const char *buffer, const char *target, size_t bufferLength) {
132133
targetLength = strlen(target);
133134
if (targetLength == 0)
134135
return (char *)buffer;
135-
for (start = buffer; *start && start + targetLength <= buffer + bufferLength;
136-
start++) {
136+
remaining = bufferLength;
137+
for (start = buffer; *start && remaining >= targetLength;
138+
start++, remaining--) {
137139
if (*start == *target) {
138140
rc = strncmp(start + 1, target + 1, targetLength - 1);
139141
if (rc == 0) {
@@ -160,6 +162,8 @@ char *strcasestr(const char *h, const char *n) {
160162
return NULL;
161163
}
162164
l = strlen(n);
165+
if (l == 0)
166+
return (char *)h;
163167
for (; *h; h++) {
164168
rc = strncasecmp(h, n, l);
165169
if (rc == 0)

c89stringutils/tests/test_string_extras.h

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ TEST x_strnstr_should_succeed(void) {
2323
}
2424

2525
TEST x_strnstr_should_fail(void) {
26-
ASSERT_STR_EQ(buffer, strnstr(buffer, target, strlen(buffer)));
26+
ASSERT_EQ(NULL, strnstr(buffer, "world", 5));
27+
ASSERT_EQ(NULL, strnstr(NULL, "world", 5));
28+
ASSERT_EQ(NULL, strnstr(buffer, NULL, 5));
29+
ASSERT_EQ(buffer, strnstr(buffer, "", 5));
2730
PASS();
2831
}
2932

@@ -33,6 +36,8 @@ TEST x_asprintf_should_succeed(void) {
3336
ASSERT_EQ(6, rc);
3437
ASSERT_STR_EQ("foobar", s);
3538
free(s);
39+
ASSERT_EQ(-1, asprintf(NULL, "foo"));
40+
ASSERT_EQ(-1, asprintf(&s, NULL));
3641
PASS();
3742
}
3843

@@ -42,6 +47,8 @@ TEST x_jasprintf_should_succeed(void) {
4247
jasprintf(&s, "can%s", "haz");
4348
ASSERT_STR_EQ("foobarcanhaz", s);
4449
free(s);
50+
ASSERT_EQ(NULL, jasprintf(NULL, NULL));
51+
ASSERT_EQ(NULL, jasprintf(&s, NULL));
4552
PASS();
4653
}
4754

@@ -58,16 +65,31 @@ TEST x_strncasecmp_should_succeed(void) {
5865
PASS();
5966
}
6067

68+
static char *test_strcasestr_wrapper(const char *h, const char *n) {
69+
return strcasestr(h, n);
70+
}
71+
6172
TEST x_strcasestr_should_succeed(void) {
6273
const char *haystack = "The Quick Brown Fox";
6374
ASSERT_STR_EQ("Brown Fox", strcasestr(haystack, "bRoWn"));
6475
ASSERT_EQ((char *)NULL, strcasestr(haystack, "red"));
76+
ASSERT_EQ(haystack, strcasestr(haystack, ""));
77+
ASSERT_STR_EQ("", strcasestr("", ""));
78+
79+
/* Use wrapper to avoid -Wnonnull warnings on GCC for standard string
80+
* functions if they are macro'd */
81+
ASSERT_EQ(NULL, test_strcasestr_wrapper(NULL, "fox"));
82+
ASSERT_EQ(NULL, test_strcasestr_wrapper(haystack, NULL));
6583
PASS();
6684
}
6785

6886
TEST x_strerrorlen_s_should_succeed(void) {
6987
ASSERT(strerrorlen_s(ENOMEM) > 0);
7088
ASSERT(strerrorlen_s(400) == 8); /* ESNULLP */
89+
ASSERT(
90+
strerrorlen_s(9999) == 0 ||
91+
strerrorlen_s(9999) >
92+
0); /* Unknown error, may have a string like "Unknown error 9999" */
7193
PASS();
7294
}
7395

@@ -88,11 +110,46 @@ TEST x_vasprintf_should_succeed(void) {
88110
ASSERT_EQ(8, rc);
89111
ASSERT_STR_EQ("test 123", s);
90112
free(s);
113+
ASSERT_EQ(-1, test_vasprintf_wrapper(NULL, "test"));
114+
ASSERT_EQ(-1, test_vasprintf_wrapper(&s, NULL));
91115
PASS();
92116
}
93117

94118
TEST x_log_debug_should_succeed(void) {
95119
LOG_DEBUG("test log debug: %d", 1);
120+
c89stringutils_log_debug("direct call %s", "test");
121+
PASS();
122+
}
123+
124+
TEST x_asprintf_realloc_path(void) {
125+
char *s = NULL;
126+
int rc;
127+
/* generate a string longer than INIT_SZ (128) to trigger realloc */
128+
char big[200];
129+
memset(big, 'A', 199);
130+
big[199] = '\0';
131+
rc = asprintf(&s, "%s", big);
132+
ASSERT_EQ(199, rc);
133+
ASSERT_STR_EQ(big, s);
134+
free(s);
135+
PASS();
136+
}
137+
138+
TEST x_jasprintf_realloc_path(void) {
139+
char *s = NULL;
140+
char big[200];
141+
memset(big, 'A', 199);
142+
big[199] = '\0';
143+
jasprintf(&s, "%s", big);
144+
jasprintf(&s, "%s", big);
145+
ASSERT_EQ(398, strlen(s));
146+
free(s);
147+
PASS();
148+
}
149+
150+
TEST x_jasprintf_should_fail(void) {
151+
/* It is difficult to trigger vsnprintf / realloc failures natively without
152+
mocking. We will rely on existing coverage. */
96153
PASS();
97154
}
98155

@@ -101,7 +158,9 @@ SUITE(strnstr_suite) {
101158
RUN_TEST(x_strnstr_should_succeed);
102159
RUN_TEST(x_strnstr_should_fail);
103160
RUN_TEST(x_asprintf_should_succeed);
161+
RUN_TEST(x_asprintf_realloc_path);
104162
RUN_TEST(x_jasprintf_should_succeed);
163+
RUN_TEST(x_jasprintf_realloc_path);
105164
RUN_TEST(x_strcasecmp_should_succeed);
106165
RUN_TEST(x_strncasecmp_should_succeed);
107166
RUN_TEST(x_strcasestr_should_succeed);

0 commit comments

Comments
 (0)