]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/escape: accept SIZE_MAX and perform overflow check in cescape_length() and...
authorMike Yuan <me@yhndnzj.com>
Sat, 15 Feb 2025 22:25:14 +0000 (23:25 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Feb 2025 03:37:10 +0000 (12:37 +0900)
While at it, make cescape() static inline.

src/basic/escape.c
src/basic/escape.h

index 0ab99b5a0b1d7ce3077571c9ed070bec508f5819..81d15a67cdbf9512abbc7faedf18ee1f40cac53c 100644 (file)
@@ -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;
index 65caf0dbcfa3b1660fdfadd500115ad8a1850f9b..e922b6693b317fae7684cb6485ea7678e7256c71 100644 (file)
@@ -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);