All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Michael Haggerty" <mhagger@alum.mit.edu>,
	"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 4/4] refs.c: rewrite resolve_gitlink_ref() to use parse_ref()
Date: Fri, 25 Jul 2014 17:43:59 +0700	[thread overview]
Message-ID: <1406285039-22469-5-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1406285039-22469-1-git-send-email-pclouds@gmail.com>

resolve_gitlink_ref_recursive() is less strict than the old
resolve_ref_unsafe() (which is now parse_ref()). It also has another
random limit 128 bytes for symrefs.

This brings MAXREFLEN check to resolve_ref* family. It looks like an
arbitrary limit though (added in 0ebde32 (Add 'resolve_gitlink_ref()'
helper function - 2007-04-09)

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 refs.c | 68 +++++++++++++++++++++++++-----------------------------------------
 1 file changed, 26 insertions(+), 42 deletions(-)

diff --git a/refs.c b/refs.c
index 2769f20..24503e5 100644
--- a/refs.c
+++ b/refs.c
@@ -1436,48 +1436,11 @@ static int resolve_gitlink_packed_ref(struct ref_cache *refs,
 	return 0;
 }
 
-static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
-					 const char *refname, unsigned char *sha1,
-					 int recursion)
-{
-	int fd, len;
-	char buffer[128], *p;
-	char *path;
-
-	if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
-		return -1;
-	path = *refs->name
-		? git_path_submodule(refs->name, "%s", refname)
-		: git_path("%s", refname);
-	fd = open(path, O_RDONLY);
-	if (fd < 0)
-		return resolve_gitlink_packed_ref(refs, refname, sha1);
-
-	len = read(fd, buffer, sizeof(buffer)-1);
-	close(fd);
-	if (len < 0)
-		return -1;
-	while (len && isspace(buffer[len-1]))
-		len--;
-	buffer[len] = 0;
-
-	/* Was it a detached head or an old-fashioned symlink? */
-	if (!get_sha1_hex(buffer, sha1))
-		return 0;
-
-	/* Symref? */
-	if (strncmp(buffer, "ref:", 4))
-		return -1;
-	p = buffer + 4;
-	while (isspace(*p))
-		p++;
-
-	return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);
-}
-
 int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
 {
-	int len = strlen(path), retval;
+	struct strbuf result = STRBUF_INIT;
+	int len = strlen(path), retval = 0;
+	int depth = MAXDEPTH;
 	char *submodule;
 	struct ref_cache *refs;
 
@@ -1489,8 +1452,24 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
 	refs = get_ref_cache(submodule);
 	free(submodule);
 
-	retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
-	return retval;
+	strbuf_addstr(&result, refname);
+	while (!retval) {
+		if (--depth < 0) {
+			errno = ELOOP;
+			retval = -1;
+			break;
+		}
+		path = *refs->name
+			? git_path_submodule(refs->name, "%s", result.buf)
+			: git_path("%s", result.buf);
+		retval = parse_ref(path, &result, sha1, NULL);
+		if (retval == -2) {
+			retval = resolve_gitlink_packed_ref(refs, result.buf, sha1);
+			retval = retval ? -1 : 1;
+		}
+	}
+	strbuf_release(&result);
+	return retval > 0 ? 0 : -1;
 }
 
 /*
@@ -1540,6 +1519,11 @@ int parse_ref(const char *path, struct strbuf *ref,
 	struct stat st;
 	const char *buf;
 
+	if (ref->len > MAXREFLEN) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+
 	/*
 	 * We might have to loop back here to avoid a race condition:
 	 * first we lstat() the file, then we try to read it as a link
-- 
1.9.1.346.ga2b5940

      parent reply	other threads:[~2014-07-25 10:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-25 10:43 [PATCH 0/4] Consolidate ref parsing code Nguyễn Thái Ngọc Duy
2014-07-25 10:43 ` [PATCH 1/4] strbuf.c: keep errno in strbuf_read_file() Nguyễn Thái Ngọc Duy
2014-07-25 15:41   ` Eric Sunshine
2014-09-26 10:30   ` Michael Haggerty
2014-07-25 10:43 ` [PATCH 2/4] refs.c: refactor resolve_ref_unsafe() to use strbuf internally Nguyễn Thái Ngọc Duy
2014-07-25 15:55   ` Eric Sunshine
2014-07-30 19:53     ` Junio C Hamano
2014-07-25 10:43 ` [PATCH 3/4] refs.c: move ref parsing code out of resolve_ref() Nguyễn Thái Ngọc Duy
2014-07-25 16:12   ` Ronnie Sahlberg
2014-07-26  1:50     ` Duy Nguyen
2014-07-25 10:43 ` Nguyễn Thái Ngọc Duy [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1406285039-22469-5-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mhagger@alum.mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.