Blob Blame History Raw
diff -up ./config.c.original ./config.c
--- ./config.c.original	2023-05-18 15:11:28.221121569 +0900
+++ ./config.c	2023-05-18 15:24:30.178828343 +0900
@@ -1701,6 +1701,8 @@ static int section_name_is_ok(const char
 	return 1;
 }
 
+#define GIT_CONFIG_MAX_LINE_LEN (512 * 1024)
+
 /* if new_name == NULL, the section is removed instead */
 int git_config_rename_section_in_file(const char *config_filename,
 				      const char *old_name, const char *new_name)
@@ -1709,8 +1711,9 @@ int git_config_rename_section_in_file(co
 	char *filename_buf = NULL;
 	struct lock_file *lock;
 	int out_fd;
-	char buf[1024];
+	struct strbuf buf = STRBUF_INIT;
 	FILE *config_file;
+	uint32_t line_nr = 0;
 
 	if (new_name && !section_name_is_ok(new_name)) {
 		ret = error("invalid section name: %s", new_name);
@@ -1732,15 +1735,25 @@ int git_config_rename_section_in_file(co
 		goto unlock_and_out;
 	}
 
-	while (fgets(buf, sizeof(buf), config_file)) {
+	while (!strbuf_getwholeline(&buf, config_file, '\n')) {
 		int i;
 		int length;
-		char *output = buf;
-		for (i = 0; buf[i] && isspace(buf[i]); i++)
+		char *output = buf.buf;
+
+		line_nr++;
+
+		if (buf.len >= GIT_CONFIG_MAX_LINE_LEN) {
+			ret = error(_("refusing to work with overly long line "
+				      "in '%s' on line %"PRIuMAX),
+				    config_filename, (uintmax_t)line_nr);
+			goto out;
+		}
+
+		for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++)
 			; /* do nothing */
-		if (buf[i] == '[') {
+		if (buf.buf[i] == '[') {
 			/* it's a section */
-			int offset = section_name_match(&buf[i], old_name);
+			int offset = section_name_match(&buf.buf[i], old_name);
 			if (offset > 0) {
 				ret++;
 				if (new_name == NULL) {
@@ -1785,6 +1798,7 @@ unlock_and_out:
 		ret = error("could not commit config file %s", config_filename);
 out:
 	free(filename_buf);
+	strbuf_release(&buf);
 	return ret;
 }
 
diff -up ./t/t1300-repo-config.sh.original ./t/t1300-repo-config.sh
--- ./t/t1300-repo-config.sh.original	2023-05-18 15:17:53.636877440 +0900
+++ ./t/t1300-repo-config.sh	2023-05-18 15:25:16.931647850 +0900
@@ -1122,4 +1122,34 @@ test_expect_failure 'adding a key into a
 	test_cmp expect .git/config
 '
 
+test_expect_success 'renaming a section with a long line' '
+	{
+		printf "[b]\\n" &&
+		printf "  c = d %1024s [a] e = f\\n" " " &&
+		printf "[a] g = h\\n"
+	} >y &&
+	git config -f y --rename-section a xyz &&
+	test_must_fail git config -f y b.e
+'
+
+test_expect_success 'renaming an embedded section with a long line' '
+	{
+		printf "[b]\\n" &&
+		printf "  c = d %1024s [a] [foo] e = f\\n" " " &&
+		printf "[a] g = h\\n"
+	} >y &&
+	git config -f y --rename-section a xyz &&
+	test_must_fail git config -f y foo.e
+'
+
+test_expect_success 'renaming a section with an overly-long line' '
+	{
+		printf "[b]\\n" &&
+		printf "  c = d %525000s e" " " &&
+		printf "[a] g = h\\n"
+	} >y &&
+	test_must_fail git config -f y --rename-section a xyz 2>err &&
+	test_i18ngrep "refusing to work with overly long line in .y. on line 2" err
+'
+
 test_done