From eb9cb55b944796374402ab4e2639300dc9b0b409 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Fri, 17 Dec 2010 19:43:07 +0700 Subject: Convert ce_path_match() to use struct pathspec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- read-cache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'read-cache.c') diff --git a/read-cache.c b/read-cache.c index 4f2e890b01..8b2d537f02 100644 --- a/read-cache.c +++ b/read-cache.c @@ -706,17 +706,18 @@ int ce_same_name(struct cache_entry *a, struct cache_entry *b) return ce_namelen(b) == len && !memcmp(a->name, b->name, len); } -int ce_path_match(const struct cache_entry *ce, const char **pathspec) +int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec) { const char *match, *name; + const char **ps = pathspec->raw; int len; - if (!pathspec) + if (!pathspec->nr) return 1; len = ce_namelen(ce); name = ce->name; - while ((match = *pathspec++) != NULL) { + while ((match = *ps++) != NULL) { int matchlen = strlen(match); if (matchlen > len) continue; -- cgit v1.3 From 898bbd9fb4c749afbddcb8a6b68a64b394366e44 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 15 Dec 2010 22:02:50 +0700 Subject: Convert ce_path_match() to use match_pathspec_depth() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- read-cache.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'read-cache.c') diff --git a/read-cache.c b/read-cache.c index 8b2d537f02..7772079ad3 100644 --- a/read-cache.c +++ b/read-cache.c @@ -708,29 +708,7 @@ int ce_same_name(struct cache_entry *a, struct cache_entry *b) int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec) { - const char *match, *name; - const char **ps = pathspec->raw; - int len; - - if (!pathspec->nr) - return 1; - - len = ce_namelen(ce); - name = ce->name; - while ((match = *ps++) != NULL) { - int matchlen = strlen(match); - if (matchlen > len) - continue; - if (memcmp(name, match, matchlen)) - continue; - if (matchlen && name[matchlen-1] == '/') - return 1; - if (name[matchlen] == '/' || !name[matchlen]) - return 1; - if (!matchlen) - return 1; - } - return 0; + return match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL); } /* -- cgit v1.3 From c879daa23729547fb28aa7e8783c5e4e619a9e7c Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Sat, 5 Feb 2011 17:52:21 +0700 Subject: Make hash-object more robust against malformed objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commits, trees and tags have structure. Don't let users feed git with malformed ones. Sooner or later git will die() when encountering them. Note that this patch does not check semantics. A tree that points to non-existent objects is perfectly OK (and should be so, users may choose to add commit first, then its associated tree for example). Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- builtin/hash-object.c | 2 +- cache.h | 2 +- read-cache.c | 2 +- sha1_file.c | 54 +++++++++++++++++++++++++++++++++++++++++++------- t/t1007-hash-object.sh | 13 ++++++++++++ 5 files changed, 63 insertions(+), 10 deletions(-) (limited to 'read-cache.c') diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 080af1a01b..c90acddcb2 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -15,7 +15,7 @@ static void hash_fd(int fd, const char *type, int write_object, const char *path struct stat st; unsigned char sha1[20]; if (fstat(fd, &st) < 0 || - index_fd(sha1, fd, &st, write_object, type_from_string(type), path)) + index_fd(sha1, fd, &st, write_object, type_from_string(type), path, 1)) die(write_object ? "Unable to add %s to database" : "Unable to hash %s", path); diff --git a/cache.h b/cache.h index d83d68c859..9186a56be7 100644 --- a/cache.h +++ b/cache.h @@ -501,7 +501,7 @@ extern int ie_match_stat(const struct index_state *, struct cache_entry *, struc extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int); extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); -extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path); +extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path, int format_check); extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object); extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); diff --git a/read-cache.c b/read-cache.c index 4f2e890b01..fbc12f3c3e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -92,7 +92,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st) if (fd >= 0) { unsigned char sha1[20]; - if (!index_fd(sha1, fd, st, 0, OBJ_BLOB, ce->name)) + if (!index_fd(sha1, fd, st, 0, OBJ_BLOB, ce->name, 0)) match = hashcmp(sha1, ce->sha1); /* index_fd() closed the file descriptor already */ } diff --git a/sha1_file.c b/sha1_file.c index d86a8db69a..58ca85835b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -13,6 +13,7 @@ #include "commit.h" #include "tag.h" #include "tree.h" +#include "tree-walk.h" #include "refs.h" #include "pack-revindex.h" #include "sha1-lookup.h" @@ -2471,8 +2472,37 @@ int has_sha1_file(const unsigned char *sha1) return has_loose_object(sha1); } +static void check_tree(const void *buf, size_t size) +{ + struct tree_desc desc; + struct name_entry entry; + + init_tree_desc(&desc, buf, size); + while (tree_entry(&desc, &entry)) + /* do nothing + * tree_entry() will die() on malformed entries */ + ; +} + +static void check_commit(const void *buf, size_t size) +{ + struct commit c; + memset(&c, 0, sizeof(c)); + if (parse_commit_buffer(&c, buf, size)) + die("corrupt commit"); +} + +static void check_tag(const void *buf, size_t size) +{ + struct tag t; + memset(&t, 0, sizeof(t)); + if (parse_tag_buffer(&t, buf, size)) + die("corrupt tag"); +} + static int index_mem(unsigned char *sha1, void *buf, size_t size, - int write_object, enum object_type type, const char *path) + int write_object, enum object_type type, + const char *path, int format_check) { int ret, re_allocated = 0; @@ -2490,6 +2520,14 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size, re_allocated = 1; } } + if (format_check) { + if (type == OBJ_TREE) + check_tree(buf, size); + if (type == OBJ_COMMIT) + check_commit(buf, size); + if (type == OBJ_TAG) + check_tag(buf, size); + } if (write_object) ret = write_sha1_file(buf, size, typename(type), sha1); @@ -2503,7 +2541,7 @@ static int index_mem(unsigned char *sha1, void *buf, size_t size, #define SMALL_FILE_SIZE (32*1024) int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, - enum object_type type, const char *path) + enum object_type type, const char *path, int format_check) { int ret; size_t size = xsize_t(st->st_size); @@ -2512,23 +2550,25 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, struct strbuf sbuf = STRBUF_INIT; if (strbuf_read(&sbuf, fd, 4096) >= 0) ret = index_mem(sha1, sbuf.buf, sbuf.len, write_object, - type, path); + type, path, format_check); else ret = -1; strbuf_release(&sbuf); } else if (!size) { - ret = index_mem(sha1, NULL, size, write_object, type, path); + ret = index_mem(sha1, NULL, size, write_object, type, path, + format_check); } else if (size <= SMALL_FILE_SIZE) { char *buf = xmalloc(size); if (size == read_in_full(fd, buf, size)) ret = index_mem(sha1, buf, size, write_object, type, - path); + path, format_check); else ret = error("short read %s", strerror(errno)); free(buf); } else { void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - ret = index_mem(sha1, buf, size, write_object, type, path); + ret = index_mem(sha1, buf, size, write_object, type, path, + format_check); munmap(buf, size); } close(fd); @@ -2546,7 +2586,7 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write if (fd < 0) return error("open(\"%s\"): %s", path, strerror(errno)); - if (index_fd(sha1, fd, st, write_object, OBJ_BLOB, path) < 0) + if (index_fd(sha1, fd, st, write_object, OBJ_BLOB, path, 0) < 0) return error("%s: failed to insert into database", path); break; diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh index dd32432d62..6d52b824b1 100755 --- a/t/t1007-hash-object.sh +++ b/t/t1007-hash-object.sh @@ -188,4 +188,17 @@ for args in "-w --stdin-paths" "--stdin-paths -w"; do pop_repo done +test_expect_success 'corrupt tree' ' + echo abc >malformed-tree + test_must_fail git hash-object -t tree malformed-tree +' + +test_expect_success 'corrupt commit' ' + test_must_fail git hash-object -t commit --stdin Date: Tue, 22 Feb 2011 22:43:23 +0000 Subject: update-index --refresh --porcelain: add missing const Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- cache.h | 2 +- read-cache.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'read-cache.c') diff --git a/cache.h b/cache.h index 3abf8950bd..4a758babec 100644 --- a/cache.h +++ b/cache.h @@ -511,7 +511,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); #define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */ #define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */ #define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */ -extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, char *header_msg); +extern int refresh_index(struct index_state *, unsigned int flags, const char **pathspec, char *seen, const char *header_msg); struct lock_file { struct lock_file *next; diff --git a/read-cache.c b/read-cache.c index 4f2e890b01..15b0a73b62 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1104,7 +1104,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate, } static void show_file(const char * fmt, const char * name, int in_porcelain, - int * first, char *header_msg) + int * first, const char *header_msg) { if (in_porcelain && *first && header_msg) { printf("%s\n", header_msg); @@ -1114,7 +1114,7 @@ static void show_file(const char * fmt, const char * name, int in_porcelain, } int refresh_index(struct index_state *istate, unsigned int flags, const char **pathspec, - char *seen, char *header_msg) + char *seen, const char *header_msg) { int i; int has_errors = 0; -- cgit v1.3