Blame SOURCES/git-2.27.0-cve-2023-25652-cve-2023-25815-cve-2023-29007.patch

4705dd
diff -ur b/apply.c a/apply.c
4705dd
--- b/apply.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/apply.c	2023-05-03 13:53:00.200547081 +0200
4705dd
@@ -4516,7 +4516,7 @@
4705dd
 	FILE *rej;
4705dd
 	char namebuf[PATH_MAX];
4705dd
 	struct fragment *frag;
4705dd
-	int cnt = 0;
4705dd
+	int fd, cnt = 0;
4705dd
 	struct strbuf sb = STRBUF_INIT;
4705dd
 
4705dd
 	for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) {
4705dd
@@ -4556,7 +4556,17 @@
4705dd
 	memcpy(namebuf, patch->new_name, cnt);
4705dd
 	memcpy(namebuf + cnt, ".rej", 5);
4705dd
 
4705dd
-	rej = fopen(namebuf, "w");
4705dd
+	fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
4705dd
+	if (fd < 0) {
4705dd
+		if (errno != EEXIST)
4705dd
+			return error_errno(_("cannot open %s"), namebuf);
4705dd
+		if (unlink(namebuf))
4705dd
+			return error_errno(_("cannot unlink '%s'"), namebuf);
4705dd
+		fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
4705dd
+		if (fd < 0)
4705dd
+			return error_errno(_("cannot open %s"), namebuf);
4705dd
+	}
4705dd
+	rej = fdopen(fd, "w");
4705dd
 	if (!rej)
4705dd
 		return error_errno(_("cannot open %s"), namebuf);
4705dd
 
4705dd
diff -ur b/builtin/clone.c a/builtin/clone.c
4705dd
--- b/builtin/clone.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/builtin/clone.c	2023-05-03 13:52:23.803339233 +0200
4705dd
@@ -248,6 +248,15 @@
4705dd
 		while (start < end && is_dir_sep(end[-1]))
4705dd
 			end--;
4705dd
 	}
4705dd
+	
4705dd
+	/*
4705dd
+	 * It should not be possible to overflow `ptrdiff_t` by passing in an
4705dd
+	 * insanely long URL, but GCC does not know that and will complain
4705dd
+	 * without this check.
4705dd
+	 */
4705dd
+	if (end - start < 0)
4705dd
+		die(_("No directory name could be guessed.\n"
4705dd
+		      "Please specify a directory on the command line"));
4705dd
 
4705dd
 	/*
4705dd
 	 * Strip trailing port number if we've got only a
4705dd
diff -ur b/compat/nedmalloc/nedmalloc.c a/compat/nedmalloc/nedmalloc.c
4705dd
--- b/compat/nedmalloc/nedmalloc.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/compat/nedmalloc/nedmalloc.c	2023-05-03 13:51:33.546052246 +0200
4705dd
@@ -323,7 +323,6 @@
4705dd
 }
4705dd
 static void DestroyCaches(nedpool *p) THROWSPEC
4705dd
 {
4705dd
-	if(p->caches)
4705dd
 	{
4705dd
 		threadcache *tc;
4705dd
 		int n;
4705dd
diff -ur b/compat/win32/syslog.c a/compat/win32/syslog.c
4705dd
--- b/compat/win32/syslog.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/compat/win32/syslog.c	2023-05-03 13:51:35.154061429 +0200
4705dd
@@ -43,6 +43,7 @@
4705dd
 	va_end(ap);
4705dd
 
4705dd
 	while ((pos = strstr(str, "%1")) != NULL) {
4705dd
+		size_t offset = pos - str;
4705dd
 		char *oldstr = str;
4705dd
 		str = realloc(str, st_add(++str_len, 1));
4705dd
 		if (!str) {
4705dd
@@ -50,6 +51,7 @@
4705dd
 			warning_errno("realloc failed");
4705dd
 			return;
4705dd
 		}
4705dd
+		pos = str + offset;
4705dd
 		memmove(pos + 2, pos + 1, strlen(pos));
4705dd
 		pos[1] = ' ';
4705dd
 	}
4705dd
diff -ur b/config.c a/config.c
4705dd
--- b/config.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/config.c	2023-05-03 13:50:49.378800030 +0200
4705dd
@@ -3009,9 +3009,10 @@
4705dd
 					multi_replace);
4705dd
 }
4705dd
 
4705dd
-static int section_name_match (const char *buf, const char *name)
4705dd
+static size_t section_name_match (const char *buf, const char *name)
4705dd
 {
4705dd
-	int i = 0, j = 0, dot = 0;
4705dd
+	size_t i = 0, j = 0;
4705dd
+	int dot = 0;
4705dd
 	if (buf[i] != '[')
4705dd
 		return 0;
4705dd
 	for (i = 1; buf[i] && buf[i] != ']'; i++) {
4705dd
@@ -3064,6 +3065,8 @@
4705dd
 	return 1;
4705dd
 }
4705dd
 
4705dd
+#define GIT_CONFIG_MAX_LINE_LEN (512 * 1024)
4705dd
+
4705dd
 /* if new_name == NULL, the section is removed instead */
4705dd
 static int git_config_copy_or_rename_section_in_file(const char *config_filename,
4705dd
 				      const char *old_name,
4705dd
@@ -3073,11 +3076,12 @@
4705dd
 	char *filename_buf = NULL;
4705dd
 	struct lock_file lock = LOCK_INIT;
4705dd
 	int out_fd;
4705dd
-	char buf[1024];
4705dd
+	struct strbuf buf = STRBUF_INIT;
4705dd
 	FILE *config_file = NULL;
4705dd
 	struct stat st;
4705dd
 	struct strbuf copystr = STRBUF_INIT;
4705dd
 	struct config_store_data store;
4705dd
+	uint32_t line_nr = 0;
4705dd
 
4705dd
 	memset(&store, 0, sizeof(store));
4705dd
 
4705dd
@@ -3114,16 +3118,25 @@
4705dd
 		goto out;
4705dd
 	}
4705dd
 
4705dd
-	while (fgets(buf, sizeof(buf), config_file)) {
4705dd
-		int i;
4705dd
-		int length;
4705dd
+	while (!strbuf_getwholeline(&buf, config_file, '\n')) {
4705dd
+		size_t i, length;
4705dd
 		int is_section = 0;
4705dd
-		char *output = buf;
4705dd
-		for (i = 0; buf[i] && isspace(buf[i]); i++)
4705dd
+		char *output = buf.buf;
4705dd
+
4705dd
+		line_nr++;
4705dd
+
4705dd
+		if (buf.len >= GIT_CONFIG_MAX_LINE_LEN) {
4705dd
+			ret = error(_("refusing to work with overly long line "
4705dd
+				      "in '%s' on line %"PRIuMAX),
4705dd
+				    config_filename, (uintmax_t)line_nr);
4705dd
+			goto out;
4705dd
+		}
4705dd
+
4705dd
+		for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++)
4705dd
 			; /* do nothing */
4705dd
-		if (buf[i] == '[') {
4705dd
+		if (buf.buf[i] == '[') {
4705dd
 			/* it's a section */
4705dd
-			int offset;
4705dd
+			size_t offset;
4705dd
 			is_section = 1;
4705dd
 
4705dd
 			/*
4705dd
@@ -3140,7 +3153,7 @@
4705dd
 				strbuf_reset(&copystr);
4705dd
 			}
4705dd
 
4705dd
-			offset = section_name_match(&buf[i], old_name);
4705dd
+			offset = section_name_match(&buf.buf[i], old_name);
4705dd
 			if (offset > 0) {
4705dd
 				ret++;
4705dd
 				if (new_name == NULL) {
4705dd
@@ -3215,6 +3228,7 @@
4705dd
 out_no_rollback:
4705dd
 	free(filename_buf);
4705dd
 	config_store_data_clear(&store);
4705dd
+	strbuf_release(&buf;;
4705dd
 	return ret;
4705dd
 }
4705dd
 
4705dd
diff -ur b/gettext.c a/gettext.c
4705dd
--- b/gettext.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/gettext.c	2023-05-03 13:47:46.953758294 +0200
4705dd
@@ -173,6 +173,8 @@
4705dd
 		setlocale(LC_CTYPE, "C");
4705dd
 }
4705dd
 
4705dd
+int git_gettext_enabled = 0;
4705dd
+
4705dd
 void git_setup_gettext(void)
4705dd
 {
4705dd
 	const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
4705dd
@@ -194,6 +196,8 @@
4705dd
 	init_gettext_charset("git");
4705dd
 	textdomain("git");
4705dd
 
4705dd
+	git_gettext_enabled = 1;
4705dd
+	
4705dd
 	free(p);
4705dd
 }
4705dd
 
4705dd
diff -ur b/gettext.h a/gettext.h
4705dd
--- b/gettext.h	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/gettext.h	2023-05-03 13:46:54.234457247 +0200
4705dd
@@ -31,9 +31,11 @@
4705dd
 int use_gettext_poison(void);
4705dd
 
4705dd
 #ifndef NO_GETTEXT
4705dd
+extern int git_gettext_enabled;
4705dd
 void git_setup_gettext(void);
4705dd
 int gettext_width(const char *s);
4705dd
 #else
4705dd
+#define git_gettext_enabled (0)
4705dd
 static inline void git_setup_gettext(void)
4705dd
 {
4705dd
 	use_gettext_poison(); /* getenv() reentrancy paranoia */
4705dd
@@ -48,7 +50,8 @@
4705dd
 {
4705dd
 	if (!*msgid)
4705dd
 		return "";
4705dd
-	return use_gettext_poison() ? "# GETTEXT POISON #" : gettext(msgid);
4705dd
+	return use_gettext_poison() ? "# GETTEXT POISON #" :
4705dd
+		!git_gettext_enabled ? msgid : gettext(msgid);
4705dd
 }
4705dd
 
4705dd
 static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2)
4705dd
@@ -56,6 +59,8 @@
4705dd
 {
4705dd
 	if (use_gettext_poison())
4705dd
 		return "# GETTEXT POISON #";
4705dd
+	if (!git_gettext_enabled)
4705dd
+		return n == 1 ? msgid : plu;
4705dd
 	return ngettext(msgid, plu, n);
4705dd
 }
4705dd
 
4705dd
diff -ur b/range-diff.c a/range-diff.c
4705dd
--- b/range-diff.c	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/range-diff.c	2023-05-03 13:44:54.980776256 +0200
4705dd
@@ -25,17 +25,6 @@
4705dd
 	struct object_id oid;
4705dd
 };
4705dd
 
4705dd
-static size_t find_end_of_line(char *buffer, unsigned long size)
4705dd
-{
4705dd
-	char *eol = memchr(buffer, '\n', size);
4705dd
-
4705dd
-	if (!eol)
4705dd
-		return size;
4705dd
-
4705dd
-	*eol = '\0';
4705dd
-	return eol + 1 - buffer;
4705dd
-}
4705dd
-
4705dd
 /*
4705dd
  * Reads the patches into a string list, with the `util` field being populated
4705dd
  * as struct object_id (will need to be free()d).
4705dd
@@ -48,7 +37,7 @@
4705dd
 	struct patch_util *util = NULL;
4705dd
 	int in_header = 1;
4705dd
 	char *line, *current_filename = NULL;
4705dd
-	int offset, len;
4705dd
+	ssize_t len;
4705dd
 	size_t size;
4705dd
 
4705dd
 	argv_array_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges",
4705dd
@@ -83,11 +72,18 @@
4705dd
 
4705dd
 	line = contents.buf;
4705dd
 	size = contents.len;
4705dd
-	for (offset = 0; size > 0; offset += len, size -= len, line += len) {
4705dd
+	for (; size > 0; size -= len, line += len) {
4705dd
 		const char *p;
4705dd
+		char *eol;
4705dd
+
4705dd
+		eol = memchr(line, '\n', size);
4705dd
+		if (eol) {
4705dd
+			*eol = '\0';
4705dd
+			len = eol + 1 - line;
4705dd
+		} else {
4705dd
+			len = size;
4705dd
+		}
4705dd
 
4705dd
-		len = find_end_of_line(line, size);
4705dd
-		line[len - 1] = '\0';
4705dd
 		if (skip_prefix(line, "commit ", &p)) {
4705dd
 			if (util) {
4705dd
 				string_list_append(list, buf.buf)->util = util;
4705dd
@@ -129,7 +125,8 @@
4705dd
 			strbuf_addch(&buf, '\n');
4705dd
 			if (!util->diff_offset)
4705dd
 				util->diff_offset = buf.len;
4705dd
-			line[len - 1] = '\n';
4705dd
+			if (eol)
4705dd
+				*eol = '\n';
4705dd
 			orig_len = len;
4705dd
 			len = parse_git_diff_header(&root, &linenr, 0, line,
4705dd
 						    len, size, &patch);
4705dd
diff -ur b/t/t1300-config.sh a/t/t1300-config.sh
4705dd
--- b/t/t1300-config.sh	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/t/t1300-config.sh	2023-05-03 13:39:43.864071831 +0200
4705dd
@@ -616,6 +616,36 @@
4705dd
 	test_must_fail git config --rename-section branch.zwei "bogus name"
4705dd
 '
4705dd
 
4705dd
+test_expect_success 'renaming a section with a long line' '
4705dd
+	{
4705dd
+		printf "[b]\\n" &&
4705dd
+		printf "  c = d %1024s [a] e = f\\n" " " &&
4705dd
+		printf "[a] g = h\\n"
4705dd
+	} >y &&
4705dd
+	git config -f y --rename-section a xyz &&
4705dd
+	test_must_fail git config -f y b.e
4705dd
+'
4705dd
+
4705dd
+test_expect_success 'renaming an embedded section with a long line' '
4705dd
+	{
4705dd
+		printf "[b]\\n" &&
4705dd
+		printf "  c = d %1024s [a] [foo] e = f\\n" " " &&
4705dd
+		printf "[a] g = h\\n"
4705dd
+	} >y &&
4705dd
+	git config -f y --rename-section a xyz &&
4705dd
+	test_must_fail git config -f y foo.e
4705dd
+'
4705dd
+
4705dd
+test_expect_success 'renaming a section with an overly-long line' '
4705dd
+	{
4705dd
+		printf "[b]\\n" &&
4705dd
+		printf "  c = d %525000s e" " " &&
4705dd
+		printf "[a] g = h\\n"
4705dd
+	} >y &&
4705dd
+	test_must_fail git config -f y --rename-section a xyz 2>err &&
4705dd
+	test_i18ngrep "refusing to work with overly long line in .y. on line 2" err
4705dd
+'
4705dd
+
4705dd
 cat >> .git/config << EOF
4705dd
   [branch "zwei"] a = 1 [branch "vier"]
4705dd
 EOF
4705dd
diff -ur b/t/t4115-apply-symlink.sh a/t/t4115-apply-symlink.sh
4705dd
--- b/t/t4115-apply-symlink.sh	2020-06-01 17:49:27.000000000 +0200
4705dd
+++ a/t/t4115-apply-symlink.sh	2023-05-03 13:39:01.453839938 +0200
4705dd
@@ -44,4 +44,17 @@
4705dd
 
4705dd
 '
4705dd
 
4705dd
+test_expect_success SYMLINKS '--reject removes .rej symlink if it exists' '
4705dd
+	test_when_finished "git reset --hard && git clean -dfx" &&
4705dd
+	test_commit file &&
4705dd
+	echo modified >file.t &&
4705dd
+	git diff -- file.t >patch &&
4705dd
+	echo modified-again >file.t &&
4705dd
+	ln -s foo file.t.rej &&
4705dd
+	test_must_fail git apply patch --reject 2>err &&
4705dd
+	test_i18ngrep "Rejected hunk" err &&
4705dd
+	test_path_is_missing foo &&
4705dd
+	test_path_is_file file.t.rej
4705dd
+'
4705dd
+
4705dd
 test_done
4705dd
Only in a: .vscode