From: Mike Yuan Date: Sat, 15 Feb 2025 22:25:14 +0000 (+0100) Subject: basic/escape: accept SIZE_MAX and perform overflow check in cescape_length() and... X-Git-Tag: v258-rc1~1329^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7de7c7b6dce69b25b8c504224473c7ede5007354;p=thirdparty%2Fsystemd.git basic/escape: accept SIZE_MAX and perform overflow check in cescape_length() and decescape() too While at it, make cescape() static inline. --- diff --git a/src/basic/escape.c b/src/basic/escape.c index 0ab99b5a0b1..81d15a67cdb 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -80,10 +80,15 @@ char* cescape_length(const char *s, size_t n) { const char *f; char *r, *t; + /* Does C style string escaping. May be reversed with cunescape(). */ + assert(s || n == 0); - /* Does C style string escaping. May be reversed with - * cunescape(). */ + if (n == SIZE_MAX) + n = strlen(s); + + if (n > (SIZE_MAX - 1) / 4) + return NULL; r = new(char, n*4 + 1); if (!r) @@ -97,12 +102,6 @@ char* cescape_length(const char *s, size_t n) { return r; } -char* cescape(const char *s) { - assert(s); - - return cescape_length(s, strlen(s)); -} - int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul) { int r = 1; @@ -486,6 +485,12 @@ char* decescape(const char *s, const char *bad, size_t len) { assert(s || len == 0); + if (len == SIZE_MAX) + len = strlen(s); + + if (len > (SIZE_MAX - 1) / 4) + return NULL; + t = buf = new(char, len * 4 + 1); if (!buf) return NULL; diff --git a/src/basic/escape.h b/src/basic/escape.h index 65caf0dbcfa..e922b6693b3 100644 --- a/src/basic/escape.h +++ b/src/basic/escape.h @@ -41,9 +41,11 @@ typedef enum ShellEscapeFlags { SHELL_ESCAPE_EMPTY = 1 << 2, /* Format empty arguments as "". */ } ShellEscapeFlags; -char* cescape(const char *s); -char* cescape_length(const char *s, size_t n); int cescape_char(char c, char *buf); +char* cescape_length(const char *s, size_t n); +static inline char* cescape(const char *s) { + return cescape_length(s, SIZE_MAX); +} int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);