X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=read-cache.c;h=3c32aae7e8ae63bccad83a603f2b86c66965cd26;hb=f252281102514d8d3cc15a3df5ae633619c93835;hp=2512565260f7664b08b0dc772a67cb26ac01f81f;hpb=283c8eef6c9a4e379c73904d2bc22b19341b15c8;p=git.git diff --git a/read-cache.c b/read-cache.c index 251256526..3c32aae7e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -346,6 +346,70 @@ int ce_path_match(const struct cache_entry *ce, const char **pathspec) return 0; } +/* + * We fundamentally don't like some paths: we don't want + * dot or dot-dot anywhere, and for obvious reasons don't + * want to recurse into ".git" either. + * + * Also, we don't want double slashes or slashes at the + * end that can make pathnames ambiguous. + */ +static int verify_dotfile(const char *rest) +{ + /* + * The first character was '.', but that + * has already been discarded, we now test + * the rest. + */ + switch (*rest) { + /* "." is not allowed */ + case '\0': case '/': + return 0; + + /* + * ".git" followed by NUL or slash is bad. This + * shares the path end test with the ".." case. + */ + case 'g': + if (rest[1] != 'i') + break; + if (rest[2] != 't') + break; + rest += 2; + /* fallthrough */ + case '.': + if (rest[1] == '\0' || rest[1] == '/') + return 0; + } + return 1; +} + +int verify_path(const char *path) +{ + char c; + + goto inside; + for (;;) { + if (!c) + return 1; + if (c == '/') { +inside: + c = *path++; + switch (c) { + default: + continue; + case '/': case '\0': + break; + case '.': + if (verify_dotfile(path)) + continue; + } + return 0; + } + c = *path++; + } +} + /* * Do we have another file that has the beginning components being a * proper superset of the name we're trying to add? @@ -487,6 +551,8 @@ int add_cache_entry(struct cache_entry *ce, int option) if (!ok_to_add) return -1; + if (!verify_path(ce->name)) + return -1; if (!skip_df_check && check_file_directory_conflict(ce, pos, ok_to_replace)) { @@ -640,7 +706,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size) SHA1_Init(&c); SHA1_Update(&c, hdr, size - 20); SHA1_Final(sha1, &c); - if (memcmp(sha1, (void *)hdr + size - 20, 20)) + if (memcmp(sha1, (char *) hdr + size - 20, 20)) return error("bad index file sha1 signature"); return 0; } @@ -704,7 +770,7 @@ int read_cache(void) offset = sizeof(*hdr); for (i = 0; i < active_nr; i++) { - struct cache_entry *ce = map + offset; + struct cache_entry *ce = (struct cache_entry *) ((char *) map + offset); offset = offset + ce_size(ce); active_cache[i] = ce; } @@ -717,10 +783,11 @@ int read_cache(void) * in 4-byte network byte order. */ unsigned long extsize; - memcpy(&extsize, map + offset + 4, 4); + memcpy(&extsize, (char *) map + offset + 4, 4); extsize = ntohl(extsize); - if (read_index_extension(map + offset, - map + offset + 8, extsize) < 0) + if (read_index_extension(((const char *) map) + offset, + (char *) map + offset + 8, + extsize) < 0) goto unmap; offset += 8; offset += extsize; @@ -754,13 +821,13 @@ static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len) } write_buffer_len = buffered; len -= partial; - data += partial; + data = (char *) data + partial; } return 0; } static int write_index_ext_header(SHA_CTX *context, int fd, - unsigned long ext, unsigned long sz) + unsigned int ext, unsigned int sz) { ext = htonl(ext); sz = htonl(sz);