diff --git a/src/basic/escape.c b/src/basic/escape.c index 1cb7ced545..e04b435d5b 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -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/src/test/test-escape.c b/src/test/test-escape.c index da19272624..de82020d5f 100644 --- a/src/test/test-escape.c +++ b/src/test/test-escape.c @@ -219,4 +219,20 @@ TEST(quote_command_line) { "true \"\\$dollar\""); } +static void test_octescape_one(const char *s, const char *expected) { + _cleanup_free_ char *ret; + + assert_se(ret = octescape(s, strlen_ptr(s))); + log_debug("octescape(\"%s\") → \"%s\" (expected: \"%s\")", strnull(s), ret, expected); + assert_se(streq(ret, expected)); +} + +TEST(octescape) { + test_octescape_one(NULL, ""); + test_octescape_one("", ""); + test_octescape_one("foo", "foo"); + test_octescape_one("\"\\\"", "\\042\\134\\042"); + test_octescape_one("\123\213\222", "\123\\213\\222"); +} + DEFINE_TEST_MAIN(LOG_DEBUG); 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 index 0000000000..13778bf23b Binary files /dev/null and b/test/fuzz/fuzz-resource-record/clusterfuzz-testcase-minimized-fuzz-resource-record-5844226627993600 differ