From: Johan Herland <johan@herland.net>
To: Junio C Hamano <junkio@cox.net>
Cc: git@vger.kernel.org
Subject: [PATCH] Fix bug in tag parsing when thorough verification was in effect
Date: Fri, 08 Jun 2007 00:13:50 +0200 [thread overview]
Message-ID: <200706080013.50644.johan@herland.net> (raw)
In-Reply-To: <200706040251.52613.johan@herland.net>
The code that was enabled by passing a non-zero 'thorough_verify' argument
to parse_and_verify_tag_buffer() moved the 'tag_line' and 'keywords_line'
pointer variables forward in memory while checking for illegal chars.
These pointers were later used when setting the respective members on
the parsed tag object.
The fix refactors the verification loop so as to use offsets to the
'tag_line' and 'keywords_line' pointers, instead of moving the pointers
directly.
The patch also includes cleanup of the code associated with moving the
various '*_line' pointers past their initial header field identifier.
These operations are now done along with the calculation of their
corresponding '*_len' variables.
The patch also includes minor changes to expected output in associated
testcases.
The bug was discovered by inspection. Currently none of the callers of
parse_and_verify_tag_buffer() that use thorough_verify != 0, also use
the 'tag' and 'keywords' members of the parsed tag object.
Signed-off-by: Johan Herland <johan@herland.net>
---
This goes on top of the existing "Refactor the tag object" patch series.
Have fun!
...Johan
t/t3800-mktag.sh | 8 ++++----
tag.c | 49 ++++++++++++++++++++++++++-----------------------
2 files changed, 30 insertions(+), 27 deletions(-)
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index f6e3d10..ac9008a 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -186,7 +186,7 @@ tagger bar@baz.com
EOF
cat >expect.pat <<EOF
-^error: char67: could not verify tag name$
+^error: char66: could not verify tag name$
EOF
check_verify_failure 'verify tag-name check'
@@ -240,7 +240,7 @@ tagger bar@baz.com
EOF
cat >expect.pat <<EOF
-^error: char83: .*$
+^error: char82: .*$
EOF
check_verify_failure '"keywords" line check #1'
@@ -258,7 +258,7 @@ tagger bar@baz.com
EOF
cat >expect.pat <<EOF
-^error: char87: .*$
+^error: char86: .*$
EOF
check_verify_failure '"keywords" line check #2'
@@ -276,7 +276,7 @@ tagger bar@baz.com
EOF
cat >expect.pat <<EOF
-^error: char83: .*$
+^error: char82: .*$
EOF
check_verify_failure '"keywords" line check #3'
diff --git a/tag.c b/tag.c
index 9c95e0b..e371179 100644
--- a/tag.c
+++ b/tag.c
@@ -153,52 +153,55 @@ int parse_and_verify_tag_buffer(struct tag *item, const char *data, const unsign
if (*header_end != '\n') /* header must end with "\n\n" */
return error("char" PD_FMT ": could not find blank line after header section", header_end - data);
- /* Calculate lengths of header fields */
- type_len = tag_line == type_line ? 0 : /* 0 if not given, > 0 if given */
- (tag_line - type_line) - strlen("type \n");
- tag_len = keywords_line == tag_line ? 0 : /* 0 if not given, > 0 if given */
- (keywords_line - tag_line) - strlen("tag \n");
- keywords_len = tagger_line == keywords_line ? 0 : /* 0 if not given, > 0 if given */
- (tagger_line - keywords_line) - strlen("keywords \n");
- tagger_len = header_end == tagger_line ? 0 : /* 0 if not given, > 0 if given */
- (header_end - tagger_line) - strlen("tagger \n");
+ /*
+ * Advance header field pointers past their initial identifier.
+ * Calculate lengths of header fields (0 for fields that are not given).
+ */
+ type_line += strlen("type ");
+ type_len = tag_line > type_line ? ( tag_line - type_line) - 1 : 0;
+ tag_line += strlen("tag ");
+ tag_len = keywords_line > tag_line ? (keywords_line - tag_line) - 1 : 0;
+ keywords_line += strlen("keywords ");
+ keywords_len = tagger_line > keywords_line ? ( tagger_line - keywords_line) - 1 : 0;
+ tagger_line += strlen("tagger ");
+ tagger_len = header_end > tagger_line ? ( header_end - tagger_line) - 1 : 0;
/* Get the actual type */
if (type_len >= sizeof(type))
- return error("char" PD_FMT ": type too long", (type_line + 5) - data);
- memcpy(type, type_line + 5, type_len);
+ return error("char" PD_FMT ": type too long", (type_line) - data);
+ memcpy(type, type_line, type_len);
type[type_len] = '\0';
if (thorough_verify) {
+ unsigned long i;
+
/* Verify that the object matches */
if (verify_object(sha1, type))
return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1));
/* Verify the tag name: we don't allow control characters or spaces in it */
if (tag_len > 0) { /* tag name was given */
- tag_line += 4; /* skip past "tag " */
- for (;;) {
- unsigned char c = *tag_line++;
+ for (i = 0; i < tag_len; ++i) {
+ unsigned char c = tag_line[i];
if (c == '\n')
break;
if (c > ' ' && c != 0x7f)
continue;
- return error("char" PD_FMT ": could not verify tag name", tag_line - data);
+ return error("char" PD_FMT ": could not verify tag name", tag_line + i - data);
}
}
/* Verify the keywords line: we don't allow control characters or spaces in it, or two subsequent commas */
if (keywords_len > 0) { /* keywords line was given */
- keywords_line += 9; /* skip past "keywords " */
- for (;;) {
- unsigned char c = *keywords_line++;
+ for (i = 0; i < keywords_len; ++i) {
+ unsigned char c = keywords_line[i];
if (c == '\n')
break;
- if (c == ',' && *keywords_line == ',')
- return error("char" PD_FMT ": found empty keyword", keywords_line - data);
+ if (c == ',' && keywords_line[i + 1] == ',') /* consecutive commas */
+ return error("char" PD_FMT ": found empty keyword", keywords_line + i - data);
if (c > ' ' && c != 0x7f)
continue;
- return error("char" PD_FMT ": could not verify keywords", keywords_line - data);
+ return error("char" PD_FMT ": could not verify keywords", keywords_line + i - data);
}
}
@@ -211,7 +214,7 @@ int parse_and_verify_tag_buffer(struct tag *item, const char *data, const unsign
if (item) { /* Store parsed information into item */
if (tag_len > 0) { /* optional tag name was given */
item->tag = xmalloc(tag_len + 1);
- memcpy(item->tag, tag_line + 4, tag_len);
+ memcpy(item->tag, tag_line, tag_len);
item->tag[tag_len] = '\0';
}
else { /* optional tag name not given */
@@ -221,7 +224,7 @@ int parse_and_verify_tag_buffer(struct tag *item, const char *data, const unsign
if (keywords_len > 0) { /* optional keywords string was given */
item->keywords = xmalloc(keywords_len + 1);
- memcpy(item->keywords, keywords_line + 9, keywords_len);
+ memcpy(item->keywords, keywords_line, keywords_len);
item->keywords[keywords_len] = '\0';
}
else { /* optional keywords string not given. Set default keywords */
--
1.5.2
next prev parent reply other threads:[~2007-06-07 22:15 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-04 0:51 Refactoring the tag object; Introducing soft references (softrefs); Git 'notes' (take 2) Johan Herland
2007-06-04 0:51 ` [PATCH 0/6] Refactor the tag object Johan Herland
2007-06-04 0:52 ` [PATCH 1/6] Refactor git tag objects; make "tag" header optional; introduce new optional "keywords" header Johan Herland
2007-06-04 6:08 ` Matthias Lederhofer
2007-06-04 7:30 ` Johan Herland
2007-06-04 0:53 ` [PATCH 2/6] git-show: When showing tag objects with no tag name, show tag object's SHA1 instead of an empty string Johan Herland
2007-06-04 0:53 ` [PATCH 3/6] git-fsck: Do thorough verification of tag objects Johan Herland
2007-06-04 5:56 ` Matthias Lederhofer
2007-06-04 7:51 ` Johan Herland
2007-06-06 7:18 ` Junio C Hamano
2007-06-06 8:06 ` Johan Herland
2007-06-06 9:03 ` Junio C Hamano
2007-06-06 9:21 ` Junio C Hamano
2007-06-06 10:26 ` Johan Herland
2007-06-06 10:35 ` Junio C Hamano
2007-06-04 0:54 ` [PATCH 4/6] Documentation/git-mktag: Document the changes in tag object structure Johan Herland
2007-06-04 0:54 ` [PATCH 5/6] git-mktag tests: Fix and expand the mktag tests according to the new " Johan Herland
2007-06-04 0:54 ` [PATCH 6/6] Add fsck_verify_ref_to_tag_object() to verify that refname matches name stored in tag object Johan Herland
2007-06-04 20:32 ` [PATCH 0/6] Refactor the " Junio C Hamano
2007-06-07 22:13 ` Johan Herland [this message]
2007-06-09 18:19 ` [PATCH 0/7] Introduce soft references (softrefs) Johan Herland
2007-06-09 18:21 ` [PATCH 1/7] Softrefs: Add softrefs header file with API documentation Johan Herland
2007-06-10 6:58 ` Johannes Schindelin
2007-06-10 7:43 ` Junio C Hamano
2007-06-10 7:54 ` Johannes Schindelin
2007-06-10 14:00 ` Johan Herland
2007-06-10 14:27 ` Jakub Narebski
2007-06-10 14:45 ` [PATCH] Teach git-gc to merge unsorted softrefs Johan Herland
2007-06-09 18:22 ` [PATCH 2/7] Softrefs: Add implementation of softrefs API Johan Herland
2007-06-09 18:22 ` [PATCH 3/7] Softrefs: Add git-softref, a builtin command for adding, listing and administering softrefs Johan Herland
2007-06-09 18:23 ` [PATCH 4/7] Softrefs: Add manual page documenting git-softref and softrefs subsystem in general Johan Herland
2007-06-09 18:23 ` [PATCH 5/7] Softrefs: Add testcases for basic softrefs behaviour Johan Herland
2007-06-09 18:24 ` [PATCH 6/7] Softrefs: Administrivia associated with softrefs subsystem and git-softref builtin Johan Herland
2007-06-09 18:24 ` [PATCH 7/7] Teach git-mktag to register softrefs for all tag objects Johan Herland
2007-06-09 18:25 ` [PATCH] Change softrefs file format from text (82 bytes per entry) to binary (40 bytes per entry) Johan Herland
2007-06-10 8:02 ` Johannes Schindelin
2007-06-10 8:30 ` Junio C Hamano
2007-06-10 9:46 ` Johannes Schindelin
2007-06-10 14:03 ` Johan Herland
2007-06-09 23:55 ` Comment on weak refs Junio C Hamano
2007-06-10 1:25 ` Johan Herland
2007-06-10 6:33 ` Johannes Schindelin
2007-06-10 13:41 ` Johan Herland
2007-06-10 14:09 ` Pierre Habouzit
2007-06-10 14:25 ` Pierre Habouzit
2007-06-10 9:03 ` Pierre Habouzit
2007-06-10 15:26 ` Jakub Narebski
2007-06-09 22:57 ` Refactoring the tag object; Introducing soft references (softrefs); Git 'notes' (take 2) Steven Grimm
2007-06-09 23:16 ` Johan Herland
2007-06-10 8:29 ` Pierre Habouzit
2007-06-10 14:31 ` Johan Herland
2007-06-10 19:42 ` Steven Grimm
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=200706080013.50644.johan@herland.net \
--to=johan@herland.net \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/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).