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

[PATCH v2 4/5] refs/reftable: add fsck check for trailing newline

From
Karthik Nayak <karthik.188@gmail.com>
Date
Sep 2, 2025, 07:05 UTC
Message-ID
<20250902-228-reftable-introduce-consistency-checks-v2-4-4f96b3834779@gmail.com>
In-Reply-To
<20250902-228-reftable-introduce-consistency-checks-v2-0-4f96b3834779@gmail.com>

Introduce a fsck check for the reftable backend, which checks if the 'tables.list' contains a newline. The reftable backend writes a trailing newline when writing the 'tables.list', but it doesn't check for it when reading the file. A missing newline however indicates that the file was manually tampered with, so let's raise this as an error to the user.

Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 Documentation/fsck-msgids.adoc |  3 +++
 fsck.h                         |  1 +
 refs/reftable-backend.c        |  3 +++
 reftable/fsck.c                | 36 ++++++++++++++++++++++++++++++++++++
 reftable/reftable-fsck.h       |  2 ++
 t/t0614-reftable-fsck.sh       | 21 +++++++++++++++++++++
 6 files changed, 66 insertions(+)
diff --git a/Documentation/fsck-msgids.adoc b/Documentation/fsck-msgids.adoc
index 707e2fc50a..1432b1de06 100644
--- a/Documentation/fsck-msgids.adoc
+++ b/Documentation/fsck-msgids.adoc
@@ -41,6 +41,9 @@
 `badReftableStackCount`::
 	(ERROR) Mismatch in number of tables.
 
+`badReftableStackListNewline`::
+	(ERROR) Reftable stack list missing trailing newline.
+
 `badReftableTableName`::
 	(ERROR) A reftable table has an invalid name.
 
diff --git a/fsck.h b/fsck.h
index 256effc4f8..33432bae79 100644
--- a/fsck.h
+++ b/fsck.h
@@ -35,6 +35,7 @@ enum fsck_msg_type {
 	FUNC(BAD_PARENT_SHA1, ERROR)                               \
 	FUNC(BAD_REFERENT_NAME, ERROR)                             \
 	FUNC(BAD_REFTABLE_STACK_COUNT, ERROR)                      \
+	FUNC(BAD_REFTABLE_STACK_LIST_NEWLINE, ERROR)               \
 	FUNC(BAD_REFTABLE_TABLE_NAME, ERROR)                       \
 	FUNC(BAD_REF_CONTENT, ERROR)                               \
 	FUNC(BAD_REF_FILETYPE, ERROR)                              \
diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 59c39f9b52..7331513b19 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -2698,6 +2698,9 @@ static int reftable_fsck_error_handler(struct reftable_fsck_info *info,
 	case REFTABLE_FSCK_ERROR_STACK_COUNT:
 		msg_id = FSCK_MSG_BAD_REFTABLE_STACK_COUNT;
 		break;
+	case REFTABLE_FSCK_ERROR_STACK_LIST_MISSING_NEWLINE:
+		msg_id = FSCK_MSG_BAD_REFTABLE_STACK_LIST_NEWLINE;
+		break;
 	default:
 		BUG("unknown fsck error: %d", info->error);
 	}
diff --git a/reftable/fsck.c b/reftable/fsck.c
index 20e6bfb0f1..9a7f22c56b 100644
--- a/reftable/fsck.c
+++ b/reftable/fsck.c
@@ -1,7 +1,31 @@
 #include "basics.h"
+#include "reftable-error.h"
 #include "reftable-fsck.h"
 #include "stack.h"
 
+static int reftable_fsck_stack_contains_newline(const char *list_file)
+{
+	FILE *f = fopen(list_file, "r");
+	int c = 0;
+
+	if (f == NULL) {
+		if (errno == ENOENT)
+			return 0;
+		return REFTABLE_IO_ERROR;
+	}
+
+	if (fseek(f, 0, SEEK_END) == 0) {
+		long size = ftell(f);
+		if (size <= 0)
+			return REFTABLE_IO_ERROR;
+		fseek(f, -1, SEEK_END);
+		c = fgetc(f);
+	}
+	fclose(f);
+
+	return c == '\n';
+}
+
 static int reftable_fsck_valid_stack_count(struct reftable_stack *st)
 {
 	DIR *dir = opendir(st->reftable_dir);
@@ -69,6 +93,18 @@ int reftable_fsck_check(struct reftable_stack *stack,
 		}
 	}
 
+	verbose_fn("Checking trailing newline in stack list", cb_data);
+
+	if (!reftable_fsck_stack_contains_newline(stack->list_file)) {
+		struct reftable_fsck_info info = {
+			.error = REFTABLE_FSCK_ERROR_STACK_LIST_MISSING_NEWLINE,
+			.path = "reftable/tables.list",
+			.msg = "trailing newline missing in stack list"
+		};
+
+		err = report_fn(&info, cb_data);
+	}
+
 	verbose_fn("Checking reftable tables count", cb_data);
 
 	if (!reftable_fsck_valid_stack_count(stack)) {
diff --git a/reftable/reftable-fsck.h b/reftable/reftable-fsck.h
index beba1bdd1a..17df661da8 100644
--- a/reftable/reftable-fsck.h
+++ b/reftable/reftable-fsck.h
@@ -8,6 +8,8 @@ enum reftable_fsck_error {
 	REFTABLE_FSCK_ERROR_TABLE_NAME = -1,
 	/* Incorrect number of tables present */
 	REFTABLE_FSCK_ERROR_STACK_COUNT = -2,
+	/* Newline missing at the end of the stack list */
+	REFTABLE_FSCK_ERROR_STACK_LIST_MISSING_NEWLINE = -3,
 };
 
 /* Represents an individual error encountered during the FSCK checks. */
diff --git a/t/t0614-reftable-fsck.sh b/t/t0614-reftable-fsck.sh
index 3a34a31890..3b119eae62 100755
--- a/t/t0614-reftable-fsck.sh
+++ b/t/t0614-reftable-fsck.sh
@@ -75,4 +75,25 @@ test_expect_success 'table count should be checked' '
 	)
 '
 
+test_expect_success 'stack list must contain trailing newline' '
+	test_when_finished "rm -rf repo" &&
+	git init repo &&
+	(
+		cd repo &&
+		git commit --allow-empty -m initial &&
+
+		git refs verify 2>err &&
+		test_must_be_empty err &&
+
+		printf "%s" "$(cat .git/reftable/tables.list)" >.git/reftable/tables.list.tmp &&
+		mv .git/reftable/tables.list.tmp .git/reftable/tables.list &&
+
+		test_must_fail git refs verify 2>err &&
+		cat >expect <<-EOF &&
+		error: reftable/tables.list: badReftableStackListNewline: trailing newline missing in stack list
+		EOF
+		test_cmp expect err
+	)
+'
+
 test_done
-- 
2.50.1
Previous: Karthik NayakNext: Junio C Hamano
Message 13 of 18 in “refs/reftable: add fsck checks”
  1. 0/5 refs/reftable: add fsck checksKarthik Nayak, Sep 2, 2025
  2. 1/5 fsck: order 'fsck_msg_type' alphabeticallyKarthik Nayak, Sep 2, 2025
  3. Junio C HamanoSep 2, 2025
  4. Karthik NayakSep 8, 2025
  5. 2/5 refs/reftable: add fsck check for checking the table nameKarthik Nayak, Sep 2, 2025
  6. Patrick SteinhardtSep 3, 2025
  7. shejialuoSep 3, 2025
  8. Karthik NayakSep 9, 2025
  9. Karthik NayakSep 9, 2025
  10. 3/5 refs/reftable: add fsck check for number of tablesKarthik Nayak, Sep 2, 2025
  11. Patrick SteinhardtSep 3, 2025
  12. Karthik NayakSep 15, 2025
  13. 4/5 refs/reftable: add fsck check for trailing newlineKarthik Nayak, Sep 2, 2025
  14. Junio C HamanoSep 2, 2025
  15. Patrick SteinhardtSep 3, 2025
  16. 5/5 refs/reftable: add fsck check for incorrect update indexKarthik Nayak, Sep 2, 2025
  17. Junio C HamanoSep 2, 2025
  18. Karthik NayakSep 18, 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.