diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 3b920418b09..51b11ab9c7d 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -862,7 +862,6 @@ int executable_is_script(const char *path, char **interpreter) { int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) { _cleanup_free_ char *status = NULL; char *t, *f; - size_t len; int r; assert(terminator); @@ -914,9 +913,7 @@ int get_proc_field(const char *filename, const char *pattern, const char *termin t--; } - len = strcspn(t, terminator); - - f = strndup(t, len); + f = strdupcspn(t, terminator); if (!f) return -ENOMEM; diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c index b710f07929e..e743033b1ea 100644 --- a/src/basic/hostname-util.c +++ b/src/basic/hostname-util.c @@ -62,7 +62,7 @@ int gethostname_full(GetHostnameFlags flags, char **ret) { } if (FLAGS_SET(flags, GET_HOSTNAME_SHORT)) - buf = strndup(s, strcspn(s, ".")); + buf = strdupcspn(s, "."); else buf = strdup(s); if (!buf) diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 5e3a92c7c0c..577afd37f42 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -1201,3 +1201,19 @@ size_t strspn_from_end(const char *str, const char *accept) { return n; } + +char *strdupspn(const char *a, const char *accept) { + if (isempty(a) || isempty(accept)) + return strdup(""); + + return strndup(a, strspn(a, accept)); +} + +char *strdupcspn(const char *a, const char *reject) { + if (isempty(a)) + return strdup(""); + if (isempty(reject)) + return strdup(a); + + return strndup(a, strcspn(a, reject)); +} diff --git a/src/basic/string-util.h b/src/basic/string-util.h index a78b7960e36..684b7d5c118 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -240,3 +240,6 @@ bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok); char *string_replace_char(char *str, char old_char, char new_char); size_t strspn_from_end(const char *str, const char *accept); + +char *strdupspn(const char *a, const char *accept); +char *strdupcspn(const char *a, const char *reject); diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c index 624c63ec98b..e1ddf97914c 100644 --- a/src/binfmt/binfmt.c +++ b/src/binfmt/binfmt.c @@ -40,11 +40,9 @@ static int apply_rule(const char *filename, unsigned line, const char *rule) { assert(rule[0]); _cleanup_free_ char *rulename = NULL; - const char *e; int r; - e = strchrnul(rule + 1, rule[0]); - rulename = strndup(rule + 1, e - rule - 1); + rulename = strdupcspn(rule + 1, CHAR_TO_STR(rule[0])); if (!rulename) return log_oom(); diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c index ddca11d908e..4f2d3aaeb86 100644 --- a/src/locale/localed-util.c +++ b/src/locale/localed-util.c @@ -505,7 +505,9 @@ int find_legacy_keymap(Context *c, char **ret) { /* If that didn't work, strip off the * other layouts from the entry, too */ - x = strndup(a[1], strcspn(a[1], ",")); + x = strdupcspn(a[1], ","); + if (!x) + return -ENOMEM; if (startswith_comma(c->x11_layout, x)) matching = 1; } diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 7f1fe4f4dcd..a7d5267696f 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -175,15 +175,13 @@ static int image_new( static int extract_pretty(const char *path, const char *suffix, char **ret) { _cleanup_free_ char *name = NULL; const char *p; - size_t n; assert(path); assert(ret); p = last_path_component(path); - n = strcspn(p, "/"); - name = strndup(p, n); + name = strdupcspn(p, "/"); if (!name) return -ENOMEM; diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index 5c9dd61898a..a43d53073ff 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -108,7 +108,7 @@ static int url_from_catalog(sd_journal *j, char **ret) { weblink += strspn(weblink, " \t"); /* Cut out till next whitespace/newline */ - url = strndup(weblink, strcspn(weblink, WHITESPACE)); + url = strdupcspn(weblink, WHITESPACE); if (!url) return log_oom();