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
prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).