From 7ff7161044552a9802d2fe57c234faae147f0d01 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Thu, 9 May 2024 21:55:09 +0800 Subject: [PATCH 1/3] basic/utf8: modernize utf8_is_valid_n a bit --- src/basic/utf8.c | 12 ++++++------ src/basic/utf8.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/basic/utf8.c b/src/basic/utf8.c index 15deef1ffd..fd1e96c68c 100644 --- a/src/basic/utf8.c +++ b/src/basic/utf8.c @@ -130,24 +130,24 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newlin return true; } -char *utf8_is_valid_n(const char *str, size_t len_bytes) { +char* utf8_is_valid_n(const char *str, size_t len_bytes) { /* Check if the string is composed of valid utf8 characters. If length len_bytes is given, stop after * len_bytes. Otherwise, stop at NUL. */ assert(str); - for (const char *p = str; len_bytes != SIZE_MAX ? (size_t) (p - str) < len_bytes : *p != '\0'; ) { + for (size_t i = 0; len_bytes != SIZE_MAX ? i < len_bytes : str[i] != '\0'; ) { int len; - if (_unlikely_(*p == '\0') && len_bytes != SIZE_MAX) + if (_unlikely_(str[i] == '\0')) return NULL; /* embedded NUL */ - len = utf8_encoded_valid_unichar(p, - len_bytes != SIZE_MAX ? len_bytes - (p - str) : SIZE_MAX); + len = utf8_encoded_valid_unichar(str + i, + len_bytes != SIZE_MAX ? len_bytes - i : SIZE_MAX); if (_unlikely_(len < 0)) return NULL; /* invalid character */ - p += len; + i += len; } return (char*) str; diff --git a/src/basic/utf8.h b/src/basic/utf8.h index 962312c5fb..fbd3318987 100644 --- a/src/basic/utf8.h +++ b/src/basic/utf8.h @@ -14,9 +14,9 @@ bool unichar_is_valid(char32_t c); -char *utf8_is_valid_n(const char *str, size_t len_bytes) _pure_; -static inline char *utf8_is_valid(const char *s) { - return utf8_is_valid_n(s, SIZE_MAX); +char* utf8_is_valid_n(const char *str, size_t len_bytes) _pure_; +static inline char* utf8_is_valid(const char *str) { + return utf8_is_valid_n(str, SIZE_MAX); } char *ascii_is_valid(const char *s) _pure_; char *ascii_is_valid_n(const char *str, size_t len); From 4d06bf59229ed766ba8fdd83c2712701291277f4 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Thu, 9 May 2024 21:58:36 +0800 Subject: [PATCH 2/3] basic/utf8: modernize ascii_is_valid_n, make ascii_is_valid static inline --- src/basic/utf8.c | 23 +++++------------------ src/basic/utf8.h | 7 +++++-- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/basic/utf8.c b/src/basic/utf8.c index fd1e96c68c..4d1b31f26d 100644 --- a/src/basic/utf8.c +++ b/src/basic/utf8.c @@ -271,27 +271,14 @@ char *utf8_escape_non_printable_full(const char *str, size_t console_width, bool return str_realloc(p); } -char *ascii_is_valid(const char *str) { - /* Check whether the string consists of valid ASCII bytes, - * i.e values between 0 and 127, inclusive. */ +char* ascii_is_valid_n(const char *str, size_t len) { + /* Check whether the string consists of valid ASCII bytes, i.e values between 1 and 127, inclusive. + * Stops at len, or NUL byte if len is SIZE_MAX. */ assert(str); - for (const char *p = str; *p; p++) - if ((unsigned char) *p >= 128) - return NULL; - - return (char*) str; -} - -char *ascii_is_valid_n(const char *str, size_t len) { - /* Very similar to ascii_is_valid(), but checks exactly len - * bytes and rejects any NULs in that range. */ - - assert(str); - - for (size_t i = 0; i < len; i++) - if ((unsigned char) str[i] >= 128 || str[i] == 0) + for (size_t i = 0; len != SIZE_MAX ? i < len : str[i] != '\0'; i++) + if ((unsigned char) str[i] >= 128 || str[i] == '\0') return NULL; return (char*) str; diff --git a/src/basic/utf8.h b/src/basic/utf8.h index fbd3318987..301c50cc2f 100644 --- a/src/basic/utf8.h +++ b/src/basic/utf8.h @@ -18,8 +18,11 @@ char* utf8_is_valid_n(const char *str, size_t len_bytes) _pure_; static inline char* utf8_is_valid(const char *str) { return utf8_is_valid_n(str, SIZE_MAX); } -char *ascii_is_valid(const char *s) _pure_; -char *ascii_is_valid_n(const char *str, size_t len); + +char* ascii_is_valid_n(const char *str, size_t len) _pure_; +static inline char* ascii_is_valid(const char *str) { + return ascii_is_valid_n(str, SIZE_MAX); +} int utf8_to_ascii(const char *str, char replacement_char, char **ret); From e2b812c8045b574fa164d850ef50f426ae9e1df5 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Thu, 9 May 2024 22:01:07 +0800 Subject: [PATCH 3/3] string-util: introduce string_is_safe_ascii helper --- src/basic/string-util.h | 4 ++++ src/libsystemd-network/sd-dhcp-server.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/basic/string-util.h b/src/basic/string-util.h index a032ee8d6a..b5da8bea05 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -8,6 +8,7 @@ #include "alloc-util.h" #include "macro.h" #include "string-util-fundamental.h" +#include "utf8.h" /* What is interpreted as whitespace? */ #define WHITESPACE " \t\n\r" @@ -234,6 +235,9 @@ static inline int strdup_to(char **ret, const char *src) { } bool string_is_safe(const char *p) _pure_; +static inline bool string_is_safe_ascii(const char *p) { + return ascii_is_valid(p) && string_is_safe(p); +} DISABLE_WARNING_STRINGOP_TRUNCATION; static inline void strncpy_exact(char *buf, const char *src, size_t buf_len) { diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 4967f066dc..25b4cafaa5 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -271,7 +271,7 @@ int sd_dhcp_server_set_boot_server_name(sd_dhcp_server *server, const char *name int sd_dhcp_server_set_boot_filename(sd_dhcp_server *server, const char *filename) { assert_return(server, -EINVAL); - if (filename && (!string_is_safe(filename) || !ascii_is_valid(filename))) + if (filename && !string_is_safe_ascii(filename)) return -EINVAL; return free_and_strdup(&server->boot_filename, filename);