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

[PATCH 1/6] remote: drop auto-strlen behavior of make_branch() and make_rewrite()

From
Jeff King <peff@peff.net>
Date
Apr 10, 2020, 19:43 UTC
Message-ID
<20200410194341.GA1363756@coredump.intra.peff.net>
In-Reply-To
<20200410194211.GA1363484@coredump.intra.peff.net>

The make_branch() and make_rewrite() functions can take a NUL-terminated string or a ptr/len pair. They use a sentinel value of "0" for the len to tell the difference between the two. However, when parsing config like:

  [branch ""]
  merge = whatever
whose key flattens to:
  branch..merge

we might actually have a zero-length branch name. This is obviously nonsense, but the current code would consider it as a NUL-terminated string and use the branch name ".merge".

We could use a better sentinel value here (like "-1"), but that gets in the way of moving to size_t, which is a more appropriate type for a ptr/len combo.

Let's instead just drop this feature and have the callers (of which there are only two total) use strlen() themselves. This simplifies the code, and lets us move to using size_t.

Signed-off-by: Jeff King <peff@peff.net>
---
 remote.c | 35 ++++++++++++-----------------------
 1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/remote.c b/remote.c
index c43196ec06..35bc3f9f2d 100644
--- a/remote.c
+++ b/remote.c
@@ -174,54 +174,43 @@ static void add_merge(struct branch *branch, const char *name)
 	branch->merge_name[branch->merge_nr++] = name;
 }
 
-static struct branch *make_branch(const char *name, int len)
+static struct branch *make_branch(const char *name, size_t len)
 {
 	struct branch *ret;
 	int i;
 
 	for (i = 0; i < branches_nr; i++) {
-		if (len ? (!strncmp(name, branches[i]->name, len) &&
-			   !branches[i]->name[len]) :
-		    !strcmp(name, branches[i]->name))
+		if (!strncmp(name, branches[i]->name, len) &&
+		    !branches[i]->name[len])
 			return branches[i];
 	}
 
 	ALLOC_GROW(branches, branches_nr + 1, branches_alloc);
 	ret = xcalloc(1, sizeof(struct branch));
 	branches[branches_nr++] = ret;
-	if (len)
-		ret->name = xstrndup(name, len);
-	else
-		ret->name = xstrdup(name);
+	ret->name = xstrndup(name, len);
 	ret->refname = xstrfmt("refs/heads/%s", ret->name);
 
 	return ret;
 }
 
-static struct rewrite *make_rewrite(struct rewrites *r, const char *base, int len)
+static struct rewrite *make_rewrite(struct rewrites *r,
+				    const char *base, size_t len)
 {
 	struct rewrite *ret;
 	int i;
 
 	for (i = 0; i < r->rewrite_nr; i++) {
-		if (len
-		    ? (len == r->rewrite[i]->baselen &&
-		       !strncmp(base, r->rewrite[i]->base, len))
-		    : !strcmp(base, r->rewrite[i]->base))
+		if (len == r->rewrite[i]->baselen &&
+		    !strncmp(base, r->rewrite[i]->base, len))
 			return r->rewrite[i];
 	}
 
 	ALLOC_GROW(r->rewrite, r->rewrite_nr + 1, r->rewrite_alloc);
 	ret = xcalloc(1, sizeof(struct rewrite));
 	r->rewrite[r->rewrite_nr++] = ret;
-	if (len) {
-		ret->base = xstrndup(base, len);
-		ret->baselen = len;
-	}
-	else {
-		ret->base = xstrdup(base);
-		ret->baselen = strlen(base);
-	}
+	ret->base = xstrndup(base, len);
+	ret->baselen = len;
 	return ret;
 }
 
@@ -470,7 +459,7 @@ static void read_config(void)
 		const char *head_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flag);
 		if (head_ref && (flag & REF_ISSYMREF) &&
 		    skip_prefix(head_ref, "refs/heads/", &head_ref)) {
-			current_branch = make_branch(head_ref, 0);
+			current_branch = make_branch(head_ref, strlen(head_ref));
 		}
 	}
 	git_config(handle_config, NULL);
@@ -1584,7 +1573,7 @@ struct branch *branch_get(const char *name)
 	if (!name || !*name || !strcmp(name, "HEAD"))
 		ret = current_branch;
 	else
-		ret = make_branch(name, 0);
+		ret = make_branch(name, strlen(name));
 	set_merge(ret);
 	return ret;
 }
-- 
2.26.0.414.ge3a6455e3d
Previous: Jeff KingNext: Junio C Hamano
Message 2 of 16 in “better handling of gigantic config files”
  1. 0/6 better handling of gigantic config filesJeff King, Apr 10, 2020
  2. 1/6 remote: drop auto-strlen behavior of make_branch() and make_rewrite()Jeff King, Apr 10, 2020
  3. Junio C HamanoApr 10, 2020
  4. 2/6 parse_config_key(): return subsection len as size_tJeff King, Apr 10, 2020
  5. 3/6 config: drop useless length variable in write_pair()Jeff King, Apr 10, 2020
  6. Junio C HamanoApr 10, 2020
  7. 4/6 git_config_parse_key(): return baselen as size_tJeff King, Apr 10, 2020
  8. 5/6 config: use size_t to store parsed variable baselenJeff King, Apr 10, 2020
  9. 6/6 config: reject parsing of files over INT_MAXJeff King, Apr 10, 2020
  10. Junio C HamanoApr 10, 2020
  11. Jeff KingApr 10, 2020
  12. Taylor BlauApr 13, 2020
  13. Junio C HamanoApr 13, 2020
  14. Taylor BlauApr 13, 2020
  15. Jeff KingApr 13, 2020
  16. Taylor BlauApr 13, 2020

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.