Skip to content

Commit a6b77bb

Browse files
committed
fix: jv_dump_string_trunc should not break unicode characters
1 parent fa6a2ff commit a6b77bb

2 files changed

Lines changed: 23 additions & 9 deletions

File tree

src/jv_print.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,16 +381,17 @@ jv jv_dump_string(jv x, int flags) {
381381
}
382382

383383
char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize) {
384-
x = jv_dump_string(x,0);
385-
const char* p = jv_string_value(x);
386-
const size_t len = strlen(p);
387-
strncpy(outbuf, p, bufsize);
388-
outbuf[bufsize - 1] = 0;
384+
x = jv_dump_string(x, 0);
385+
const char *str = jv_string_value(x);
386+
const size_t len = strlen(str);
387+
strncpy(outbuf, str, bufsize);
389388
if (len > bufsize - 1 && bufsize >= 4) {
390-
// Indicate truncation with '...'
391-
outbuf[bufsize - 2]='.';
392-
outbuf[bufsize - 3]='.';
393-
outbuf[bufsize - 4]='.';
389+
// Indicate truncation with '...' without breaking UTF-8.
390+
const char *s = jvp_utf8_backtrack(outbuf + bufsize - 4, outbuf, NULL);
391+
if (s) bufsize = s + 4 - outbuf;
392+
strcpy(outbuf + bufsize - 4, "...");
393+
} else {
394+
outbuf[bufsize - 1] = '\0';
394395
}
395396
jv_free(x);
396397
return outbuf;

tests/jq.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,19 @@ try -. catch .
17881788
"very-long-string"
17891789
"string (\"very-long-...) cannot be negated"
17901790

1791+
try (.-.) catch .
1792+
"very-long-string"
1793+
"string (\"very-long-...) and string (\"very-long-...) cannot be subtracted"
1794+
1795+
"x" * range(0; 12; 2) + "☆" * 5 | try -. catch .
1796+
null
1797+
"string (\"☆☆☆...) cannot be negated"
1798+
"string (\"xx☆☆...) cannot be negated"
1799+
"string (\"xxxx☆☆...) cannot be negated"
1800+
"string (\"xxxxxx☆...) cannot be negated"
1801+
"string (\"xxxxxxxx...) cannot be negated"
1802+
"string (\"xxxxxxxxxx...) cannot be negated"
1803+
17911804
join(",")
17921805
["1",2,true,false,3.4]
17931806
"1,2,true,false,3.4"

0 commit comments

Comments
 (0)