From 31c8221acb7c7acaea6ce2c680c2985581ce0066 Mon Sep 17 00:00:00 2001 From: Josh Micich Date: Thu, 14 May 2009 15:49:10 -0700 Subject: mktree: validate entry type in input Previously mktree would accept tree entries which had a mismatch between the declared type and the actual type of object. Check the actual type of the object when it is available locally. Signed-off-by: Josh Micich Signed-off-by: Junio C Hamano --- builtin-mktree.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/builtin-mktree.c b/builtin-mktree.c index 73b0abbd8..dc4f1a711 100644 --- a/builtin-mktree.c +++ b/builtin-mktree.c @@ -71,7 +71,8 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m { char *ptr, *ntr; unsigned mode; - enum object_type type; + enum object_type mode_type; /* object type derived from mode */ + enum object_type obj_type; /* object type derived from sha */ char *path; unsigned char sha1[20]; @@ -94,17 +95,8 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m if (S_ISGITLINK(mode)) allow_missing = 1; - if (!allow_missing) - type = sha1_object_info(sha1, NULL); - else - type = object_type(mode); - - if (type < 0) - die("object %s unavailable", sha1_to_hex(sha1)); *ntr++ = 0; /* now at the beginning of SHA1 */ - if (type != type_from_string(ptr)) - die("object type %s mismatch (%s)", ptr, typename(type)); path = ntr + 41; /* at the beginning of name */ if (line_termination && path[0] == '"') { @@ -113,6 +105,37 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m die("invalid quoting"); path = strbuf_detach(&p_uq, NULL); } + + /* + * Object type is redundantly derivable three ways. + * These should all agree. + */ + mode_type = object_type(mode); + if (mode_type != type_from_string(ptr)) { + die("entry '%s' object type (%s) doesn't match mode type (%s)", + path, ptr, typename(mode_type)); + } + + /* Check the type of object identified by sha1 */ + obj_type = sha1_object_info(sha1, NULL); + if (obj_type < 0) { + if (allow_missing) { + ; /* no problem - missing objects are presumed to be of the right type */ + } else { + die("entry '%s' object %s is unavailable", path, sha1_to_hex(sha1)); + } + } else { + if (obj_type != mode_type) { + /* + * The object exists but is of the wrong type. + * This is a problem regardless of allow_missing + * because the new tree entry will never be correct. + */ + die("entry '%s' object %s is a %s but specified type was (%s)", + path, sha1_to_hex(sha1), typename(obj_type), typename(mode_type)); + } + } + append_to_tree(mode, sha1, path); } -- cgit v1.2.1