mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-17 08:17:42 -04:00
Clean up rtrim implementation
If I understand the C standard correctly, you can't actually point at a position immediately _before_ the start of an object; only at the position immediately after. According to J.2 in the standard, in its big list of undefined behavior: "The behavior is undefined in the following circumstances: ... — Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6)." So we've got to fix rtrim to not do that. Also, make it unit tested, and give it an evutil_*_ name.
This commit is contained in:
parent
370a2c0213
commit
aa59d805f5
19
http.c
19
http.c
@ -219,18 +219,25 @@ strsep(char **s, const char *del)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
rtrim(char *str)
|
||||
void
|
||||
evutil_rtrim_(char *str)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (str == NULL)
|
||||
return;
|
||||
|
||||
cp = strchr(str, '\0') - 1;
|
||||
if ((cp = strchr(str, '\0')) == NULL || (cp == str))
|
||||
return;
|
||||
|
||||
while (cp >= str && *cp == ' ')
|
||||
*cp-- = '\0';
|
||||
--cp;
|
||||
|
||||
while (*cp == ' ') {
|
||||
*cp = '\0';
|
||||
if (cp == str)
|
||||
break;
|
||||
--cp;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
@ -1927,7 +1934,7 @@ evhttp_parse_headers_(struct evhttp_request *req, struct evbuffer* buffer)
|
||||
goto error;
|
||||
|
||||
svalue += strspn(svalue, " ");
|
||||
rtrim(svalue);
|
||||
evutil_rtrim_(svalue);
|
||||
|
||||
if (evhttp_add_header(headers, skey, svalue) == -1)
|
||||
goto error;
|
||||
|
@ -434,6 +434,38 @@ end:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
test_evutil_rtrim(void *ptr)
|
||||
{
|
||||
#define TEST_TRIM(s, result) \
|
||||
do { \
|
||||
if (cp) mm_free(cp); \
|
||||
cp = s ? mm_strdup(s) : NULL; \
|
||||
evutil_rtrim_(cp); \
|
||||
if (result == NULL) \
|
||||
tt_ptr_op(cp, ==, NULL); \
|
||||
else \
|
||||
tt_str_op(cp, ==, result); \
|
||||
} while(0)
|
||||
|
||||
char *cp = NULL;
|
||||
(void) ptr;
|
||||
|
||||
TEST_TRIM(NULL, NULL);
|
||||
TEST_TRIM("", "");
|
||||
TEST_TRIM("a", "a");
|
||||
TEST_TRIM("abcdef ghi", "abcdef ghi");
|
||||
|
||||
TEST_TRIM(" ", "");
|
||||
TEST_TRIM(" ", "");
|
||||
TEST_TRIM("a ", "a");
|
||||
TEST_TRIM("abcdef gH ", "abcdef gH");
|
||||
|
||||
end:
|
||||
if (cp)
|
||||
mm_free(cp);
|
||||
}
|
||||
|
||||
static int logsev = 0;
|
||||
static char *logmsg = NULL;
|
||||
|
||||
@ -1348,6 +1380,7 @@ struct testcase_t util_testcases[] = {
|
||||
{ "evutil_snprintf", test_evutil_snprintf, 0, NULL, NULL },
|
||||
{ "evutil_strtoll", test_evutil_strtoll, 0, NULL, NULL },
|
||||
{ "evutil_casecmp", test_evutil_casecmp, 0, NULL, NULL },
|
||||
{ "evutil_rtrim", test_evutil_rtrim, 0, NULL, NULL },
|
||||
{ "strlcpy", test_evutil_strlcpy, 0, NULL, NULL },
|
||||
{ "log", test_evutil_log, TT_FORK, NULL, NULL },
|
||||
{ "upcast", test_evutil_upcast, 0, NULL, NULL },
|
||||
|
@ -218,6 +218,10 @@ int EVUTIL_ISUPPER_(char c);
|
||||
char EVUTIL_TOUPPER_(char c);
|
||||
char EVUTIL_TOLOWER_(char c);
|
||||
|
||||
/** Remove all trailing whitespace from the end of a string */
|
||||
void evutil_rtrim_(char *);
|
||||
|
||||
|
||||
/** Helper macro. If we know that a given pointer points to a field in a
|
||||
structure, return a pointer to the structure itself. Used to implement
|
||||
our half-baked C OO. Example:
|
||||
|
Loading…
x
Reference in New Issue
Block a user