git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2] utf8.c: fix strbuf_utf8_replace() consuming data beyond input string

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Aug 10, 2014, 07:05 UTC
Message-ID
<1407654321-7509-1-git-send-email-pclouds@gmail.com>
In-Reply-To
<1406639429-28748-1-git-send-email-pclouds@gmail.com>
The main loop in strbuf_utf8_replace() could summed up as:
  while ('src' is still valid) {
    1) advance 'src' to copy ANSI escape sequences
    2) advance 'src' to copy/replace visible characters
  }

The problem is after #1, 'src' may have reached the end of the string (so 'src' points to NUL) and #2 will continue to copy that NUL as if it's a normal character. Because the output is stored in a strbuf, this NULL accounted in the 'len' field as well. Check after #1 and break the loop if necessary.

The test does not look obvious, but the combination of %>>() should make a call trace like this

  show_log()
  pretty_print_commit()
  format_commit_message()
  strbuf_expand()
  format_commit_item()
  format_and_pad_commit()
  strbuf_utf8_replace()

where %C(auto)%d would insert a color reset escape sequence in the end of the string given to strbuf_utf8_replace() and show_log() uses fwrite() to send everything to stdout (including the incorrect NUL inserted by strbuf_utf8_replace)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t4205-log-pretty-formats.sh | 7 +++++++
 utf8.c                        | 3 +++
 2 files changed, 10 insertions(+)
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 349c531..de0cc4a 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -431,6 +431,13 @@ EOF
 	test_cmp expected actual
 '
 
+test_expect_success 'strbuf_utf8_replace() not producing NUL' '
+	git log --color --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)%C(auto)%d" |
+		test_decode_color |
+		nul_to_q >actual &&
+	! grep Q actual
+'
+
 # get new digests (with no abbreviations)
 head1=$(git rev-parse --verify HEAD~0) &&
 head2=$(git rev-parse --verify HEAD~1) &&
diff --git a/utf8.c b/utf8.c
index b30790d..401a6a5 100644
--- a/utf8.c
+++ b/utf8.c
@@ -382,6 +382,9 @@ void strbuf_utf8_replace(struct strbuf *sb_src, int pos, int width,
 			dst += n;
 		}
 
+		if (src >= end)
+			break;
+
 		old = src;
 		n = utf8_width((const char**)&src, NULL);
 		if (!src) 	/* broken utf-8, do nothing */
-- 
2.1.0.rc0.78.gc0d8480
Previous: Junio C Hamano
Message 5 of 5 in “utf8.c: fix strbuf_utf8_replace copying the last NUL to dst string”
  1. utf8.c: fix strbuf_utf8_replace copying the last NUL to dst stringNguyễn Thái Ngọc Duy, Jul 29, 2014
  2. Junio C HamanoJul 29, 2014
  3. Duy NguyenJul 30, 2014
  4. Junio C HamanoJul 30, 2014
  5. utf8.c: fix strbuf_utf8_replace() consuming data beyond input stringNguyễn Thái Ngọc Duy, Aug 10, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.