if (console_width == 0)
return strdup("");
- ans = new(char, MIN(strlen(s), console_width) * 4 + 1);
+ size_t body = MIN(strlen(s), console_width) * 4;
+ ans = new(char, body + STRLEN("...") + 1);
if (!ans)
return NULL;
- memset(ans, '_', MIN(strlen(s), console_width) * 4);
- ans[MIN(strlen(s), console_width) * 4] = 0;
+ memset(ans, '_', body);
+ ans[body] = 0;
bool force_ellipsis = FLAGS_SET(flags, XESCAPE_FORCE_ELLIPSIS);
if (console_width == 0)
return strdup("");
- p = s = prev_s = malloc(strlen(str) * 4 + 1);
+ size_t body = strlen(str) * 4;
+ p = s = prev_s = malloc(body + STRLEN("…") + 1);
if (!p)
return NULL;
test_xescape_full_one(true);
}
+TEST(xescape_full_ellipsis) {
+ _cleanup_free_ char *t = NULL;
+
+ /* Every byte escapes to four columns, so the escaped output fills strlen*4 bytes and the
+ * forced ellipsis used to be written past the end of the buffer. */
+ assert_se(t = xescape_full("\001\001\001", /* bad= */ NULL, 80, XESCAPE_FORCE_ELLIPSIS));
+ ASSERT_STREQ(t, "\\x01\\x01\\x01...");
+}
+
TEST(cunescape) {
_cleanup_free_ char *unescaped = NULL;
}
}
+TEST(utf8_escape_non_printable_full_ellipsis) {
+ _cleanup_free_ char *p = NULL;
+
+ /* Every byte escapes to four columns, so the escaped output fills strlen*4 bytes and the
+ * forced ellipsis used to be written past the end of the buffer. */
+ assert_se(p = utf8_escape_non_printable_full("\001\001\001", 80, /* force_ellipsis= */ true));
+ ASSERT_STREQ(p, "\\x01\\x01\\x01…");
+}
+
TEST(utf16_to_utf8) {
const char16_t utf16[] = { htole16('a'), htole16(0xd800), htole16('b'), htole16(0xdc00), htole16('c'), htole16(0xd801), htole16(0xdc37) };
static const char utf8[] = { 'a', 'b', 'c', 0xf0, 0x90, 0x90, 0xb7 };