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

[PATCH] column: exit early when indent length is larger than width

From
HGHJ C. via GitGitGadget <gitgitgadget@gmail.com>
Date
Apr 2, 2025, 01:45 UTC
Message-ID
<pull.1937.git.git.1743558315633.gitgitgadget@gmail.com>
From: lavendarlatte <hyunjidev@gmail.com>

The code exits with "fatal size_t overflow" when indent length is larger than width. This is because when calculating cols of struct column_data, unsigned underflow happens and cols is set to negative value, then converted to size_t when calling REALLOC_ARRAY in shrink_columns() function. This can lead to allocating extremely large chunk of memory when succeeds, or crash when fails.

The change exits code early with failure reason to avoid underflow and clarify argument limitations. This change ensures that cols is always positive, making the code clearer. It also eliminates the need for warning suppression related to signed-unsigned comparisons, as cols can be safely converted to size_t.

Signed-off-by: Hyunji Choi <hyunjidev@gmail.com>
---
    column: exit early when indent length is larger than width
    
    I have sent this to git-security first for potential security check.
    Thank you Patrick for review and reply. Based on your comment I have
    updated BUG() to die() and added two tests. Also confirmed all existing
    column tests pass with new check.
    
    This is copy of his reply:
    
    Hi, thanks for your report!
    
    The use of both print_columns() and run_column_filter() is rather
    limited across the Git codebase and only covers across a small set of
    builtin commands:
    
     * git-branch(1), where the value can be changed via the --column
       command line option.
     * git-clean(1), where the values are hardcoded.
     * git-column(1), obviously.
     * git-help(1), but again the values are hardcoded.
     * git-status(1) via wt_longstatus_print_other(), but the values are
       hardcoded.
     * git-tag(1) with the --column command line option.
    
    So only git-branch(1), git-tag(1) and git-column(1) are relevant in this
    context, and I cannot think of any way to exploit these in a meaningful
    way. I also think that --column options are unlikely to be used in any
    scripts.
    
    So all in all I think it's fine to discuss this on our normal mailing
    list and fix the issue in the open. But I'd maybe wait a day or two for
    others to chime in before doing so. Given that these values are
    user-controlled we probably shouldn't use BUG() because it isn't. die()
    would likely be a better fit. We should also have one or two tests to
    verify that things work as expected.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1937%2Flavendarlatte%2Findent-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1937/lavendarlatte/indent-v1
Pull-Request: https://github.com/git/git/pull/1937
 column.c          |  6 ++++++
 t/t9002-column.sh | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)
diff --git a/column.c b/column.c
index 93fae316b45..692fefafabd 100644
--- a/column.c
+++ b/column.c
@@ -186,6 +186,9 @@ void print_columns(const struct string_list *list, unsigned int colopts,
 
 	if (opts && (0 > opts->padding))
 		BUG("padding must be non-negative");
+	if (opts && (opts->width > 0) && opts->indent &&
+		(opts->width < strlen(opts->indent)))
+		die("length of indent cannot exceed width");
 	if (!list->nr)
 		return;
 	assert((colopts & COL_ENABLE_MASK) != COL_AUTO);
@@ -367,6 +370,9 @@ int run_column_filter(int colopts, const struct column_options *opts)
 
 	if (opts && (0 > opts->padding))
 		BUG("padding must be non-negative");
+	if (opts && (opts->width > 0) && opts->indent &&
+		(opts->width < strlen(opts->indent)))
+		die("length of indent cannot exceed width");
 	if (fd_out != -1)
 		return -1;
 
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
index 7353815c11b..1b448be4567 100755
--- a/t/t9002-column.sh
+++ b/t/t9002-column.sh
@@ -206,4 +206,26 @@ EOF
 	test_cmp expected actual
 '
 
+test_expect_success 'length of indent cannot exceed width' '
+	cat >input <<\EOF &&
+1 2 3 4 5 6
+EOF
+	cat >expected <<\EOF &&
+fatal: length of indent cannot exceed width
+EOF
+	test_must_fail git column --mode=column --width=1 --indent="--" <input >actual 2>&1 &&
+	test_cmp expected actual
+'
+
+test_expect_success 'padding must be non-negative checked before indent length' '
+	cat >input <<\EOF &&
+1 2 3 4 5 6
+EOF
+	cat >expected <<\EOF &&
+fatal: --padding must be non-negative
+EOF
+	test_must_fail git column --mode=column --padding=-1 --width=1 --indent="--" <input >actual 2>&1 &&
+	test_cmp expected actual
+'
+
 test_done

base-commit: 5b97a56fa0e7d580dc8865b73107407c9b3f0eff
-- 
gitgitgadget
Message 1 of 1 in “column: exit early when indent length is larger than width”
  1. column: exit early when indent length is larger than widthHJ C. via GitGitGadget, Apr 2, 2025

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.