]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
escape: fix wrong octescape of bad character
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Dec 2022 03:00:41 +0000 (12:00 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Dec 2022 03:18:10 +0000 (12:18 +0900)
Fixes a bug introduced by 95052df3760523e1f3bb9705c918d85aae7fb431.

This also makes octescape() support NULL or zero length string.

Fixes [oss-fuzz#54059](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=54059).

Fixes #25643.

src/basic/escape.c
test/fuzz/fuzz-resource-record/clusterfuzz-testcase-minimized-fuzz-resource-record-5844226627993600 [new file with mode: 0644]

index 1cb7ced545dd9f2e925688303ea7f5c2a0859691..e04b435d5b9fb51c04385fc25cea403117c46819 100644 (file)
@@ -445,31 +445,30 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl
 }
 
 char* octescape(const char *s, size_t len) {
-        char *r, *t;
-        const char *f;
+        char *buf, *t;
 
-        /* Escapes all chars in bad, in addition to \ and " chars,
-         * in \nnn style escaping. */
+        /* Escapes all chars in bad, in addition to \ and " chars, in \nnn style escaping. */
 
-        r = new(char, len * 4 + 1);
-        if (!r)
+        assert(s || len == 0);
+
+        t = buf = new(char, len * 4 + 1);
+        if (!buf)
                 return NULL;
 
-        for (f = s, t = r; f < s + len; f++) {
+        for (size_t i = 0; i < len; i++) {
+                uint8_t u = (uint8_t) s[i];
 
-                if (*f < ' ' || *f >= 127 || IN_SET(*f, '\\', '"')) {
+                if (u < ' ' || u >= 127 || IN_SET(u, '\\', '"')) {
                         *(t++) = '\\';
-                        *(t++) = '0' + (*f >> 6);
-                        *(t++) = '0' + ((*f >> 3) & 8);
-                        *(t++) = '0' + (*f & 8);
+                        *(t++) = '0' + (u >> 6);
+                        *(t++) = '0' + ((u >> 3) & 7);
+                        *(t++) = '0' + (u & 7);
                 } else
-                        *(t++) = *f;
+                        *(t++) = u;
         }
 
         *t = 0;
-
-        return r;
-
+        return buf;
 }
 
 static char* strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
diff --git a/test/fuzz/fuzz-resource-record/clusterfuzz-testcase-minimized-fuzz-resource-record-5844226627993600 b/test/fuzz/fuzz-resource-record/clusterfuzz-testcase-minimized-fuzz-resource-record-5844226627993600
new file mode 100644 (file)
index 0000000..13778bf
Binary files /dev/null and b/test/fuzz/fuzz-resource-record/clusterfuzz-testcase-minimized-fuzz-resource-record-5844226627993600 differ