From 9b8ff18319965c7e599a70c2a1fab65823b53536 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 May 2018 13:07:37 +0200 Subject: [PATCH 1/2] string-util: add new memory_startswith() helper We have code like this at various placer, let's make things shorter and more readable with a helper for it. --- src/basic/string-util.h | 18 ++++++++++++++++++ src/test/test-string-util.c | 13 +++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/basic/string-util.h b/src/basic/string-util.h index 5a10eeabfe..aa00724266 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -209,3 +209,21 @@ static inline size_t strlen_ptr(const char *s) { return strlen(s); } + +/* Like startswith(), but operates on arbitrary memory blocks */ +static inline void *memory_startswith(const void *p, size_t sz, const char *token) { + size_t n; + + assert(token); + + n = strlen(token); + if (sz < n) + return NULL; + + assert(p); + + if (memcmp(p, token, n) != 0) + return NULL; + + return (uint8_t*) p + n; +} diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c index 965e2c5028..eac12ac7af 100644 --- a/src/test/test-string-util.c +++ b/src/test/test-string-util.c @@ -406,6 +406,18 @@ static void test_strlen_ptr(void) { assert_se(strlen_ptr(NULL) == 0); } +static void test_memory_startswith(void) { + assert_se(streq(memory_startswith("", 0, ""), "")); + assert_se(streq(memory_startswith("", 1, ""), "")); + assert_se(streq(memory_startswith("x", 2, ""), "x")); + assert_se(!memory_startswith("", 1, "x")); + assert_se(!memory_startswith("", 1, "xxxxxxxx")); + assert_se(streq(memory_startswith("xxx", 4, "x"), "xx")); + assert_se(streq(memory_startswith("xxx", 4, "xx"), "x")); + assert_se(streq(memory_startswith("xxx", 4, "xxx"), "")); + assert_se(!memory_startswith("xxx", 4, "xxxx")); +} + int main(int argc, char *argv[]) { test_string_erase(); test_ascii_strcasecmp_n(); @@ -433,6 +445,7 @@ int main(int argc, char *argv[]) { test_split_pair(); test_first_word(); test_strlen_ptr(); + test_memory_startswith(); return 0; } From d27b725abf64a19a6b2f99332b663f17ad046771 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 May 2018 13:09:03 +0200 Subject: [PATCH 2/2] tree-wide: make use of memory_startswith() at various places --- src/basic/log.c | 8 ++------ src/coredump/coredump.c | 11 ++++------- src/import/curl-util.c | 13 ++++--------- src/libsystemd/sd-bus/bus-socket.c | 11 ++++------- src/shared/dns-domain.c | 5 +---- src/shared/logs-show.c | 9 +++------ 6 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/basic/log.c b/src/basic/log.c index 5db65f276f..167f0f5533 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -1037,13 +1037,9 @@ int log_struct_iovec_internal( return -error; } - for (i = 0; i < n_input_iovec; i++) { - if (input_iovec[i].iov_len < STRLEN("MESSAGE=")) - continue; - - if (memcmp(input_iovec[i].iov_base, "MESSAGE=", STRLEN("MESSAGE=")) == 0) + for (i = 0; i < n_input_iovec; i++) + if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) break; - } if (_unlikely_(i >= n_input_iovec)) /* Couldn't find MESSAGE=? */ return -error; diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index c1f396b1ac..1c470e60da 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -852,21 +852,18 @@ static void map_context_fields(const struct iovec *iovec, const char* context[]) assert(context); for (i = 0; i < ELEMENTSOF(context_field_names); i++) { - size_t l; + char *p; if (!context_field_names[i]) continue; - l = strlen(context_field_names[i]); - if (iovec->iov_len < l) - continue; - - if (memcmp(iovec->iov_base, context_field_names[i], l) != 0) + p = memory_startswith(iovec->iov_base, iovec->iov_len, context_field_names[i]); + if (!p) continue; /* Note that these strings are NUL terminated, because we made sure that a trailing NUL byte is in the * buffer, though not included in the iov_len count. (see below) */ - context[i] = (char*) iovec->iov_base + l; + context[i] = p; break; } } diff --git a/src/import/curl-util.c b/src/import/curl-util.c index 0f81866d33..2fba6e29dd 100644 --- a/src/import/curl-util.c +++ b/src/import/curl-util.c @@ -365,19 +365,14 @@ struct curl_slist *curl_slist_new(const char *first, ...) { } int curl_header_strdup(const void *contents, size_t sz, const char *field, char **value) { - const char *p = contents; - size_t l; + const char *p; char *s; - l = strlen(field); - if (sz < l) + p = memory_startswith(contents, sz, field); + if (!p) return 0; - if (memcmp(p, field, l) != 0) - return 0; - - p += l; - sz -= l; + sz -= p - (const char*) contents; if (memchr(p, 0, sz)) return 0; diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c index 04839bada4..57c5391423 100644 --- a/src/libsystemd/sd-bus/bus-socket.c +++ b/src/libsystemd/sd-bus/bus-socket.c @@ -248,16 +248,13 @@ static bool line_equals(const char *s, size_t m, const char *line) { } static bool line_begins(const char *s, size_t m, const char *word) { - size_t l; + const char *p; - l = strlen(word); - if (m < l) + p = memory_startswith(s, m, word); + if (!p) return false; - if (memcmp(s, word, l) != 0) - return false; - - return m == l || (m > l && s[l] == ' '); + return IN_SET(*p, 0, ' '); } static int verify_anonymous_token(sd_bus *b, const char *p, size_t l) { diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c index 5ec9eed8ea..f7f544c96c 100644 --- a/src/shared/dns-domain.c +++ b/src/shared/dns-domain.c @@ -353,10 +353,7 @@ int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, if (encoded_size <= 0 || encoded_size > DNS_LABEL_MAX) return -EINVAL; - if (encoded_size < sizeof(IDNA_ACE_PREFIX)-1) - return 0; - - if (memcmp(encoded, IDNA_ACE_PREFIX, sizeof(IDNA_ACE_PREFIX) -1) != 0) + if (!memory_startswith(encoded, encoded_size, IDNA_ACE_PREFIX)) return 0; input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size); diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 47becbf37c..af788391ad 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -832,8 +832,7 @@ static int output_json( char *n; unsigned u; - if (length >= 9 && - memcmp(data, "_BOOT_ID=", 9) == 0) + if (memory_startswith(data, length, "_BOOT_ID=")) continue; eq = memchr(data, '=', length); @@ -882,10 +881,8 @@ static int output_json( size_t m; unsigned u; - /* We already printed the boot id, from the data in - * the header, hence let's suppress it here */ - if (length >= 9 && - memcmp(data, "_BOOT_ID=", 9) == 0) + /* We already printed the boot id, from the data in the header, hence let's suppress it here */ + if (memory_startswith(data, length, "_BOOT_ID=")) continue; eq = memchr(data, '=', length);