diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/attr.c | 34 | ||||
| -rw-r--r-- | src/attr_file.c | 54 | ||||
| -rw-r--r-- | src/attr_file.h | 6 | ||||
| -rw-r--r-- | src/buffer.h | 7 | ||||
| -rw-r--r-- | src/config_file.c | 2 | ||||
| -rw-r--r-- | src/crlf.c | 4 | ||||
| -rw-r--r-- | src/diff.c | 3 | ||||
| -rw-r--r-- | src/diff_output.c | 35 | ||||
| -rw-r--r-- | src/filter.c | 10 | ||||
| -rw-r--r-- | src/ignore.c | 9 | ||||
| -rw-r--r-- | src/indexer.c | 6 | ||||
| -rw-r--r-- | src/khash.h | 16 | ||||
| -rw-r--r-- | src/odb_loose.c | 16 | ||||
| -rw-r--r-- | src/odb_pack.c | 2 | ||||
| -rw-r--r-- | src/path.c | 14 | ||||
| -rw-r--r-- | src/pkt.c | 35 | ||||
| -rw-r--r-- | src/pkt.h | 6 | ||||
| -rw-r--r-- | src/pool.c | 12 | ||||
| -rw-r--r-- | src/protocol.c | 13 | ||||
| -rw-r--r-- | src/refs.c | 5 | ||||
| -rw-r--r-- | src/refspec.c | 4 | ||||
| -rw-r--r-- | src/remote.c | 18 | ||||
| -rw-r--r-- | src/repository.c | 6 | ||||
| -rw-r--r-- | src/revwalk.c | 2 | ||||
| -rw-r--r-- | src/transports/http.c | 26 | ||||
| -rw-r--r-- | src/tree.c | 2 |
26 files changed, 220 insertions, 127 deletions
diff --git a/src/attr.c b/src/attr.c index 3e3a7e749..120d12737 100644 --- a/src/attr.c +++ b/src/attr.c @@ -23,10 +23,11 @@ int git_attr_get( *value = NULL; - if ((error = git_attr_path__init( - &path, pathname, git_repository_workdir(repo))) < 0 || - (error = collect_attr_files(repo, pathname, &files)) < 0) - return error; + if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0) + return -1; + + if ((error = collect_attr_files(repo, pathname, &files)) < 0) + goto cleanup; attr.name = name; attr.name_hash = git_attr_file__name_hash(name); @@ -38,13 +39,14 @@ int git_attr_get( if (pos >= 0) { *value = ((git_attr_assignment *)git_vector_get( &rule->assigns, pos))->value; - goto found; + goto cleanup; } } } -found: +cleanup: git_vector_free(&files); + git_attr_path__free(&path); return error; } @@ -70,10 +72,11 @@ int git_attr_get_many( memset((void *)values, 0, sizeof(const char *) * num_attr); - if ((error = git_attr_path__init( - &path, pathname, git_repository_workdir(repo))) < 0 || - (error = collect_attr_files(repo, pathname, &files)) < 0) - return error; + if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0) + return -1; + + if ((error = collect_attr_files(repo, pathname, &files)) < 0) + goto cleanup; info = git__calloc(num_attr, sizeof(attr_get_many_info)); GITERR_CHECK_ALLOC(info); @@ -108,6 +111,7 @@ int git_attr_get_many( cleanup: git_vector_free(&files); + git_attr_path__free(&path); git__free(info); return error; @@ -128,10 +132,11 @@ int git_attr_foreach( git_attr_assignment *assign; git_strmap *seen = NULL; - if ((error = git_attr_path__init( - &path, pathname, git_repository_workdir(repo))) < 0 || - (error = collect_attr_files(repo, pathname, &files)) < 0) - return error; + if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0) + return -1; + + if ((error = collect_attr_files(repo, pathname, &files)) < 0) + goto cleanup; seen = git_strmap_alloc(); GITERR_CHECK_ALLOC(seen); @@ -158,6 +163,7 @@ int git_attr_foreach( cleanup: git_strmap_free(seen); git_vector_free(&files); + git_attr_path__free(&path); return error; } diff --git a/src/attr_file.c b/src/attr_file.c index e34053fc3..25c21b1fd 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -251,27 +251,50 @@ git_attr_assignment *git_attr_rule__lookup_assignment( int git_attr_path__init( git_attr_path *info, const char *path, const char *base) { - assert(info && path); - info->path = path; - info->basename = strrchr(path, '/'); - if (info->basename) - info->basename++; - if (!info->basename || !*info->basename) - info->basename = path; + /* build full path as best we can */ + git_buf_init(&info->full, 0); if (base != NULL && git_path_root(path) < 0) { - git_buf full_path = GIT_BUF_INIT; - if (git_buf_joinpath(&full_path, base, path) < 0) + if (git_buf_joinpath(&info->full, base, path) < 0) + return -1; + info->path = info->full.ptr + strlen(base); + } else { + if (git_buf_sets(&info->full, path) < 0) return -1; - info->is_dir = (int)git_path_isdir(full_path.ptr); - git_buf_free(&full_path); - return 0; + info->path = info->full.ptr; } - info->is_dir = (int)git_path_isdir(path); + + /* remove trailing slashes */ + while (info->full.size > 0) { + if (info->full.ptr[info->full.size - 1] != '/') + break; + info->full.size--; + } + info->full.ptr[info->full.size] = '\0'; + + /* skip leading slashes in path */ + while (*info->path == '/') + info->path++; + + /* find trailing basename component */ + info->basename = strrchr(info->path, '/'); + if (info->basename) + info->basename++; + if (!info->basename || !*info->basename) + info->basename = info->path; + + info->is_dir = (int)git_path_isdir(info->full.ptr); return 0; } +void git_attr_path__free(git_attr_path *info) +{ + git_buf_free(&info->full); + info->path = NULL; + info->basename = NULL; +} + /* * From gitattributes(5): @@ -353,6 +376,8 @@ int git_attr_fnmatch__parse( if (*scan == '/') { spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH; slash_count++; + if (pattern == scan) + pattern++; } /* remember if we see an unescaped wildcard in pattern */ else if ((*scan == '*' || *scan == '.' || *scan == '[') && @@ -378,7 +403,8 @@ int git_attr_fnmatch__parse( /* given an unrooted fullpath match from a file inside a repo, * prefix the pattern with the relative directory of the source file */ - spec->pattern = git_pool_malloc(pool, sourcelen + spec->length + 1); + spec->pattern = git_pool_malloc( + pool, (uint32_t)(sourcelen + spec->length + 1)); if (spec->pattern) { memcpy(spec->pattern, source, sourcelen); memcpy(spec->pattern + sourcelen, pattern, spec->length); diff --git a/src/attr_file.h b/src/attr_file.h index 677534158..10851bc49 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -10,6 +10,7 @@ #include "git2/attr.h" #include "vector.h" #include "pool.h" +#include "buffer.h" #define GIT_ATTR_FILE ".gitattributes" #define GIT_ATTR_FILE_INREPO "info/attributes" @@ -54,9 +55,10 @@ typedef struct { } git_attr_file; typedef struct { + git_buf full; const char *path; const char *basename; - int is_dir; + int is_dir; } git_attr_path; /* @@ -114,6 +116,8 @@ extern git_attr_assignment *git_attr_rule__lookup_assignment( extern int git_attr_path__init( git_attr_path *info, const char *path, const char *base); +extern void git_attr_path__free(git_attr_path *info); + extern int git_attr_assignment__parse( git_repository *repo, /* needed to expand macros */ git_pool *pool, diff --git a/src/buffer.h b/src/buffer.h index 294ff6961..1cf588a62 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -93,11 +93,16 @@ GIT_INLINE(int) git_buf_joinpath(git_buf *buf, const char *a, const char *b) return git_buf_join(buf, '/', a, b); } -GIT_INLINE(const char *) git_buf_cstr(git_buf *buf) +GIT_INLINE(const char *) git_buf_cstr(const git_buf *buf) { return buf->ptr; } +GIT_INLINE(size_t) git_buf_len(const git_buf *buf) +{ + return buf->size; +} + void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf); #define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1) diff --git a/src/config_file.c b/src/config_file.c index 7841ea00f..be0977475 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -1233,7 +1233,7 @@ static int parse_multiline_variable(diskfile_backend *cfg, git_buf *value, int i * standard, this character **has** to be last one in the buf, with * no whitespace after it */ assert(is_multiline_var(value->ptr)); - git_buf_truncate(value, value->size - 1); + git_buf_truncate(value, git_buf_len(value) - 1); proc_line = fixup_line(line, in_quotes); if (proc_line == NULL) { diff --git a/src/crlf.c b/src/crlf.c index 536b50f1e..8fe588a35 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -105,7 +105,7 @@ static int crlf_load_attributes(struct crlf_attrs *ca, git_repository *repo, con static int drop_crlf(git_buf *dest, const git_buf *source) { const char *scan = source->ptr, *next; - const char *scan_end = source->ptr + source->size; + const char *scan_end = git_buf_cstr(source) + git_buf_len(source); /* Main scan loop. Find the next carriage return and copy the * whole chunk up to that point to the destination buffer. @@ -138,7 +138,7 @@ static int crlf_apply_to_odb(git_filter *self, git_buf *dest, const git_buf *sou assert(self && dest && source); /* Empty file? Nothing to do */ - if (source->size == 0) + if (git_buf_len(source) == 0) return 0; /* Heuristics to see if we can skip the conversion. diff --git a/src/diff.c b/src/diff.c index b239031a2..5d70b822b 100644 --- a/src/diff.c +++ b/src/diff.c @@ -313,7 +313,8 @@ static git_diff_list *git_diff_list_alloc( if (!diff_pathspec_is_interesting(&opts->pathspec)) return diff; - if (git_vector_init(&diff->pathspec, opts->pathspec.count, NULL) < 0) + if (git_vector_init( + &diff->pathspec, (unsigned int)opts->pathspec.count, NULL) < 0) goto fail; for (i = 0; i < opts->pathspec.count; ++i) { diff --git a/src/diff_output.c b/src/diff_output.c index 7c5b6f276..a5a11395f 100644 --- a/src/diff_output.c +++ b/src/diff_output.c @@ -18,9 +18,10 @@ typedef struct { git_diff_list *diff; void *cb_data; git_diff_hunk_fn hunk_cb; - git_diff_line_fn line_cb; + git_diff_data_fn line_cb; unsigned int index; git_diff_delta *delta; + git_diff_range range; } diff_output_info; static int read_next_int(const char **str, int *value) @@ -62,6 +63,8 @@ static int diff_output_cb(void *priv, mmbuffer_t *bufs, int len) if (range.old_start < 0 || range.new_start < 0) return -1; + memcpy(&info->range, &range, sizeof(git_diff_range)); + return info->hunk_cb( info->cb_data, info->delta, &range, bufs[0].ptr, bufs[0].size); } @@ -76,7 +79,7 @@ static int diff_output_cb(void *priv, mmbuffer_t *bufs, int len) GIT_DIFF_LINE_CONTEXT; if (info->line_cb( - info->cb_data, info->delta, origin, bufs[1].ptr, bufs[1].size) < 0) + info->cb_data, info->delta, &info->range, origin, bufs[1].ptr, bufs[1].size) < 0) return -1; /* deal with adding and removing newline at EOF */ @@ -87,7 +90,7 @@ static int diff_output_cb(void *priv, mmbuffer_t *bufs, int len) origin = GIT_DIFF_LINE_DEL_EOFNL; return info->line_cb( - info->cb_data, info->delta, origin, bufs[2].ptr, bufs[2].size); + info->cb_data, info->delta, &info->range, origin, bufs[2].ptr, bufs[2].size); } } @@ -291,7 +294,7 @@ int git_diff_foreach( void *data, git_diff_file_fn file_cb, git_diff_hunk_fn hunk_cb, - git_diff_line_fn line_cb) + git_diff_data_fn line_cb) { int error = 0; diff_output_info info; @@ -433,7 +436,7 @@ cleanup: typedef struct { git_diff_list *diff; - git_diff_output_fn print_cb; + git_diff_data_fn print_cb; void *cb_data; git_buf *buf; } diff_print_info; @@ -491,13 +494,13 @@ static int print_compact(void *data, git_diff_delta *delta, float progress) if (git_buf_oom(pi->buf)) return -1; - return pi->print_cb(pi->cb_data, GIT_DIFF_LINE_FILE_HDR, pi->buf->ptr); + return pi->print_cb(pi->cb_data, delta, NULL, GIT_DIFF_LINE_FILE_HDR, git_buf_cstr(pi->buf), git_buf_len(pi->buf)); } int git_diff_print_compact( git_diff_list *diff, void *cb_data, - git_diff_output_fn print_cb) + git_diff_data_fn print_cb) { int error; git_buf buf = GIT_BUF_INIT; @@ -586,7 +589,7 @@ static int print_patch_file(void *data, git_diff_delta *delta, float progress) if (git_buf_oom(pi->buf)) return -1; - result = pi->print_cb(pi->cb_data, GIT_DIFF_LINE_FILE_HDR, pi->buf->ptr); + result = pi->print_cb(pi->cb_data, delta, NULL, GIT_DIFF_LINE_FILE_HDR, git_buf_cstr(pi->buf), git_buf_len(pi->buf)); if (result < 0) return result; @@ -600,7 +603,7 @@ static int print_patch_file(void *data, git_diff_delta *delta, float progress) if (git_buf_oom(pi->buf)) return -1; - return pi->print_cb(pi->cb_data, GIT_DIFF_LINE_BINARY, pi->buf->ptr); + return pi->print_cb(pi->cb_data, delta, NULL, GIT_DIFF_LINE_BINARY, git_buf_cstr(pi->buf), git_buf_len(pi->buf)); } static int print_patch_hunk( @@ -612,27 +615,23 @@ static int print_patch_hunk( { diff_print_info *pi = data; - GIT_UNUSED(d); - GIT_UNUSED(r); - git_buf_clear(pi->buf); if (git_buf_printf(pi->buf, "%.*s", (int)header_len, header) < 0) return -1; - return pi->print_cb(pi->cb_data, GIT_DIFF_LINE_HUNK_HDR, pi->buf->ptr); + return pi->print_cb(pi->cb_data, d, r, GIT_DIFF_LINE_HUNK_HDR, git_buf_cstr(pi->buf), git_buf_len(pi->buf)); } static int print_patch_line( void *data, git_diff_delta *delta, + git_diff_range *range, char line_origin, /* GIT_DIFF_LINE value from above */ const char *content, size_t content_len) { diff_print_info *pi = data; - GIT_UNUSED(delta); - git_buf_clear(pi->buf); if (line_origin == GIT_DIFF_LINE_ADDITION || @@ -645,13 +644,13 @@ static int print_patch_line( if (git_buf_oom(pi->buf)) return -1; - return pi->print_cb(pi->cb_data, line_origin, pi->buf->ptr); + return pi->print_cb(pi->cb_data, delta, range, line_origin, git_buf_cstr(pi->buf), git_buf_len(pi->buf)); } int git_diff_print_patch( git_diff_list *diff, void *cb_data, - git_diff_output_fn print_cb) + git_diff_data_fn print_cb) { int error; git_buf buf = GIT_BUF_INIT; @@ -678,7 +677,7 @@ int git_diff_blobs( git_diff_options *options, void *cb_data, git_diff_hunk_fn hunk_cb, - git_diff_line_fn line_cb) + git_diff_data_fn line_cb) { diff_output_info info; git_diff_delta delta; diff --git a/src/filter.c b/src/filter.c index 88ad0295f..d6c2e1c97 100644 --- a/src/filter.c +++ b/src/filter.c @@ -19,13 +19,13 @@ void git_text_gather_stats(git_text_stats *stats, const git_buf *text) memset(stats, 0, sizeof(*stats)); - for (i = 0; i < text->size; i++) { + for (i = 0; i < git_buf_len(text); i++) { unsigned char c = text->ptr[i]; if (c == '\r') { stats->cr++; - if (i + 1 < text->size && text->ptr[i + 1] == '\n') + if (i + 1 < git_buf_len(text) && text->ptr[i + 1] == '\n') stats->crlf++; } @@ -59,7 +59,7 @@ void git_text_gather_stats(git_text_stats *stats, const git_buf *text) } /* If file ends with EOF then don't count this EOF as non-printable. */ - if (text->size >= 1 && text->ptr[text->size - 1] == '\032') + if (git_buf_len(text) >= 1 && text->ptr[text->size - 1] == '\032') stats->nonprintable--; } @@ -127,14 +127,14 @@ int git_filters_apply(git_buf *dest, git_buf *source, git_vector *filters) src = 0; - if (source->size == 0) { + if (git_buf_len(source) == 0) { git_buf_clear(dest); return GIT_SUCCESS; } /* Pre-grow the destination buffer to more or less the size * we expect it to have */ - if (git_buf_grow(dest, source->size) < 0) + if (git_buf_grow(dest, git_buf_len(source)) < 0) return GIT_ENOMEM; for (i = 0; i < filters->length; ++i) { diff --git a/src/ignore.c b/src/ignore.c index 165754b4d..20b96c602 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -176,20 +176,23 @@ int git_ignore__lookup(git_ignores *ignores, const char *pathname, int *ignored) /* first process builtins - success means path was found */ if (ignore_lookup_in_rules( &ignores->ign_internal->rules, &path, ignored)) - return 0; + goto cleanup; /* next process files in the path */ git_vector_foreach(&ignores->ign_path, i, file) { if (ignore_lookup_in_rules(&file->rules, &path, ignored)) - return 0; + goto cleanup; } /* last process global ignores */ git_vector_foreach(&ignores->ign_global, i, file) { if (ignore_lookup_in_rules(&file->rules, &path, ignored)) - return 0; + goto cleanup; } *ignored = 0; + +cleanup: + git_attr_path__free(&path); return 0; } diff --git a/src/indexer.c b/src/indexer.c index 1f8b512c2..d2e492c39 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -376,7 +376,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz git__free(obj.data); - stats->processed = ++processed; + stats->processed = (unsigned int)++processed; } return 0; @@ -401,7 +401,7 @@ static int index_path_stream(git_buf *path, git_indexer_stream *idx, const char git_buf_truncate(path, slash); git_buf_puts(path, prefix); - git_oid_fmt(path->ptr + path->size, &idx->hash); + git_oid_fmt(path->ptr + git_buf_len(path), &idx->hash); path->size += GIT_OID_HEXSZ; git_buf_puts(path, suffix); @@ -633,7 +633,7 @@ static int index_path(git_buf *path, git_indexer *idx) git_buf_truncate(path, slash); git_buf_puts(path, prefix); - git_oid_fmt(path->ptr + path->size, &idx->hash); + git_oid_fmt(path->ptr + git_buf_len(path), &idx->hash); path->size += GIT_OID_HEXSZ; git_buf_puts(path, suffix); diff --git a/src/khash.h b/src/khash.h index f9d239336..bd67fe1f7 100644 --- a/src/khash.h +++ b/src/khash.h @@ -196,8 +196,8 @@ static const double __ac_HASH_UPPER = 0.77; SCOPE void kh_destroy_##name(kh_##name##_t *h) \ { \ if (h) { \ - kfree(h->keys); kfree(h->flags); \ - kfree(h->vals); \ + kfree((void *)h->keys); kfree(h->flags); \ + kfree((void *)h->vals); \ kfree(h); \ } \ } \ @@ -235,11 +235,11 @@ static const double __ac_HASH_UPPER = 0.77; if (!new_flags) return -1; \ memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ if (h->n_buckets < new_n_buckets) { /* expand */ \ - khkey_t *new_keys = (khkey_t*)krealloc(h->keys, new_n_buckets * sizeof(khkey_t)); \ + khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ if (!new_keys) return -1; \ h->keys = new_keys; \ if (kh_is_map) { \ - khval_t *new_vals = (khval_t*)krealloc(h->vals, new_n_buckets * sizeof(khval_t)); \ + khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ if (!new_vals) return -1; \ h->vals = new_vals; \ } \ @@ -275,8 +275,8 @@ static const double __ac_HASH_UPPER = 0.77; } \ } \ if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ - h->keys = (khkey_t*)krealloc(h->keys, new_n_buckets * sizeof(khkey_t)); \ - if (kh_is_map) h->vals = (khval_t*)krealloc(h->vals, new_n_buckets * sizeof(khval_t)); \ + h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ } \ kfree(h->flags); /* free the working space */ \ h->flags = new_flags; \ @@ -376,8 +376,8 @@ static const double __ac_HASH_UPPER = 0.77; */ static inline khint_t __ac_X31_hash_string(const char *s) { - khint_t h = *s; - if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s; + khint_t h = (khint_t)*s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; return h; } /*! @function diff --git a/src/odb_loose.c b/src/odb_loose.c index b593d1846..d028deca5 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -61,13 +61,13 @@ static int object_file_name(git_buf *name, const char *dir, const git_oid *id) git_buf_sets(name, dir); /* expand length for 40 hex sha1 chars + 2 * '/' + '\0' */ - if (git_buf_grow(name, name->size + GIT_OID_HEXSZ + 3) < 0) + if (git_buf_grow(name, git_buf_len(name) + GIT_OID_HEXSZ + 3) < 0) return -1; git_path_to_dir(name); /* loose object filename: aa/aaa... (41 bytes) */ - git_oid_pathfmt(name->ptr + name->size, id); + git_oid_pathfmt(name->ptr + git_buf_len(name), id); name->size += GIT_OID_HEXSZ + 1; name->ptr[name->size] = '\0'; @@ -81,7 +81,7 @@ static size_t get_binary_object_header(obj_hdr *hdr, git_buf *obj) unsigned char *data = (unsigned char *)obj->ptr; size_t shift, size, used = 0; - if (obj->size == 0) + if (git_buf_len(obj) == 0) return 0; c = data[used++]; @@ -90,7 +90,7 @@ static size_t get_binary_object_header(obj_hdr *hdr, git_buf *obj) size = c & 15; shift = 4; while (c & 0x80) { - if (obj->size <= used) + if (git_buf_len(obj) <= used) return 0; if (sizeof(size_t) * 8 <= shift) return 0; @@ -182,7 +182,7 @@ static int start_inflate(z_stream *s, git_buf *obj, void *out, size_t len) int status; init_stream(s, out, len); - set_stream_input(s, obj->ptr, obj->size); + set_stream_input(s, obj->ptr, git_buf_len(obj)); if ((status = inflateInit(s)) < Z_OK) return status; @@ -469,7 +469,7 @@ static int locate_object( static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) { loose_locate_object_state *sstate = (loose_locate_object_state *)state; - if (pathbuf->size - sstate->dir_len != GIT_OID_HEXSZ - 2) { + if (git_buf_len(pathbuf) - sstate->dir_len != GIT_OID_HEXSZ - 2) { /* Entry cannot be an object. Continue to next entry */ return 0; } @@ -517,7 +517,7 @@ static int locate_object_short_oid( git_path_to_dir(object_location); /* save adjusted position at end of dir so it can be restored later */ - dir_len = object_location->size; + dir_len = git_buf_len(object_location); /* Convert raw oid to hex formatted oid */ git_oid_fmt((char *)state.short_oid, short_oid); @@ -530,7 +530,7 @@ static int locate_object_short_oid( if (git_path_isdir(object_location->ptr) == false) return git_odb__error_notfound("failed to locate from short oid"); - state.dir_len = object_location->size; + state.dir_len = git_buf_len(object_location); state.short_oid_len = len; state.found = 0; diff --git a/src/odb_pack.c b/src/odb_pack.c index b91e3cadb..242200b4a 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -219,7 +219,7 @@ static int packfile_load__cb(void *_data, git_buf *path) for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p = git_vector_get(&backend->packs, i); - if (memcmp(p->pack_name, path->ptr, path->size - strlen(".idx")) == 0) + if (memcmp(p->pack_name, git_buf_cstr(path), git_buf_len(path) - strlen(".idx")) == 0) return 0; } diff --git a/src/path.c b/src/path.c index a7cf4402f..f562b0b9e 100644 --- a/src/path.c +++ b/src/path.c @@ -221,8 +221,8 @@ int git_path_prettify_dir(git_buf *path_out, const char *path, const char *base) int git_path_to_dir(git_buf *path) { if (path->asize > 0 && - path->size > 0 && - path->ptr[path->size - 1] != '/') + git_buf_len(path) > 0 && + path->ptr[git_buf_len(path) - 1] != '/') git_buf_putc(path, '/'); return git_buf_oom(path) ? -1 : 0; @@ -327,12 +327,12 @@ int git_path_walk_up( if (git__prefixcmp(path->ptr, ceiling) == 0) stop = (ssize_t)strlen(ceiling); else - stop = path->size; + stop = git_buf_len(path); } - scan = path->size; + scan = git_buf_len(path); iter.ptr = path->ptr; - iter.size = path->size; + iter.size = git_buf_len(path); iter.asize = path->asize; while (scan >= stop) { @@ -407,7 +407,7 @@ static bool _check_dir_contents( bool (*predicate)(const char *)) { bool result; - size_t dir_size = dir->size; + size_t dir_size = git_buf_len(dir); size_t sub_size = strlen(sub); /* leave base valid even if we could not make space for subdir */ @@ -503,7 +503,7 @@ int git_path_direach( if (git_path_to_dir(path) < 0) return -1; - wd_len = path->size; + wd_len = git_buf_len(path); if ((dir = opendir(path->ptr)) == NULL) { giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr); @@ -97,6 +97,25 @@ static int comment_pkt(git_pkt **out, const char *line, size_t len) return 0; } +static int err_pkt(git_pkt **out, const char *line, size_t len) +{ + git_pkt_err *pkt; + + /* Remove "ERR " from the line */ + line += 4; + len -= 4; + pkt = git__malloc(sizeof(git_pkt_err) + len + 1); + GITERR_CHECK_ALLOC(pkt); + + pkt->type = GIT_PKT_ERR; + memcpy(pkt->error, line, len); + pkt->error[len] = '\0'; + + *out = (git_pkt *) pkt; + + return 0; +} + /* * Parse an other-ref line. */ @@ -188,10 +207,8 @@ int git_pkt_parse_line( int32_t len; /* Not even enough for the length */ - if (bufflen > 0 && bufflen < PKT_LEN_SIZE) { - giterr_set(GITERR_NET, "Insufficient buffer data"); - return -1; - } + if (bufflen > 0 && bufflen < PKT_LEN_SIZE) + return GIT_ESHORTBUFFER; len = parse_len(line); if (len < 0) { @@ -211,10 +228,8 @@ int git_pkt_parse_line( * If we were given a buffer length, then make sure there is * enough in the buffer to satisfy this line */ - if (bufflen > 0 && bufflen < (size_t)len) { - giterr_set(GITERR_NET, "Insufficient buffer data for packet length"); - return -1; - } + if (bufflen > 0 && bufflen < (size_t)len) + return GIT_ESHORTBUFFER; line += PKT_LEN_SIZE; /* @@ -238,6 +253,8 @@ int git_pkt_parse_line( ret = ack_pkt(head, line, len); else if (!git__prefixcmp(line, "NAK")) ret = nak_pkt(head); + else if (!git__prefixcmp(line, "ERR ")) + ret = err_pkt(head, line, len); else if (*line == '#') ret = comment_pkt(head, line, len); else @@ -281,7 +298,7 @@ static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps len = (unsigned int) (strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + strlen(capstr) + 1 /* LF */); - git_buf_grow(buf, buf->size + len); + git_buf_grow(buf, git_buf_len(buf) + len); git_oid_fmt(oid, &head->oid); return git_buf_printf(buf, "%04xwant %s%c%s\n", len, oid, 0, capstr); @@ -23,6 +23,7 @@ enum git_pkt_type { GIT_PKT_NAK, GIT_PKT_PACK, GIT_PKT_COMMENT, + GIT_PKT_ERR, }; /* Used for multi-ack */ @@ -64,6 +65,11 @@ typedef struct { char comment[GIT_FLEX_ARRAY]; } git_pkt_comment; +typedef struct { + enum git_pkt_type type; + char error[GIT_FLEX_ARRAY]; +} git_pkt_err; + int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len); int git_pkt_buffer_flush(git_buf *buf); int git_pkt_send_flush(GIT_SOCKET s); diff --git a/src/pool.c b/src/pool.c index 8f5c7e75a..641292d06 100644 --- a/src/pool.c +++ b/src/pool.c @@ -190,7 +190,7 @@ char *git_pool_strndup(git_pool *pool, const char *str, size_t n) assert(pool && str && pool->item_size == sizeof(char)); - if ((ptr = git_pool_malloc(pool, n + 1)) != NULL) { + if ((ptr = git_pool_malloc(pool, (uint32_t)(n + 1))) != NULL) { memcpy(ptr, str, n); *(((char *)ptr) + n) = '\0'; } @@ -216,7 +216,7 @@ char *git_pool_strcat(git_pool *pool, const char *a, const char *b) len_a = a ? strlen(a) : 0; len_b = b ? strlen(b) : 0; - if ((ptr = git_pool_malloc(pool, len_a + len_b + 1)) != NULL) { + if ((ptr = git_pool_malloc(pool, (uint32_t)(len_a + len_b + 1))) != NULL) { if (len_a) memcpy(ptr, a, len_a); if (len_b) @@ -256,12 +256,12 @@ bool git_pool__ptr_in_pool(git_pool *pool, void *ptr) { git_pool_page *scan; for (scan = pool->open; scan != NULL; scan = scan->next) - if ( ((void *)scan->data) <= ptr && - (((void *)scan->data) + scan->size) > ptr) + if ((void *)scan->data <= ptr && + (void *)(((char *)scan->data) + scan->size) > ptr) return true; for (scan = pool->full; scan != NULL; scan = scan->next) - if ( ((void *)scan->data) <= ptr && - (((void *)scan->data) + scan->size) > ptr) + if ((void *)scan->data <= ptr && + (void *)(((char *)scan->data) + scan->size) > ptr) return true; return false; } diff --git a/src/protocol.c b/src/protocol.c index 4c4a7f79b..a75354121 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -17,7 +17,7 @@ int git_protocol_store_refs(git_protocol *p, const char *data, size_t len) const char *line_end, *ptr; if (len == 0) { /* EOF */ - if (buf->size != 0) { + if (git_buf_len(buf) != 0) { giterr_set(GITERR_NET, "Unexpected EOF"); return p->error = -1; } else { @@ -30,16 +30,23 @@ int git_protocol_store_refs(git_protocol *p, const char *data, size_t len) while (1) { git_pkt *pkt; - if (buf->size == 0) + if (git_buf_len(buf) == 0) return 0; - error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->size); + error = git_pkt_parse_line(&pkt, ptr, &line_end, git_buf_len(buf)); if (error == GIT_ESHORTBUFFER) return 0; /* Ask for more */ if (error < 0) return p->error = -1; git_buf_consume(buf, line_end); + + if (pkt->type == GIT_PKT_ERR) { + giterr_set(GITERR_NET, "Remote error: %s", ((git_pkt_err *)pkt)->error); + git__free(pkt); + return -1; + } + if (git_vector_insert(refs, pkt) < 0) return p->error = -1; diff --git a/src/refs.c b/src/refs.c index 7685d560c..28e8f786b 100644 --- a/src/refs.c +++ b/src/refs.c @@ -139,7 +139,7 @@ static int loose_parse_symbolic(git_reference *ref, git_buf *file_content) refname_start = (const char *)file_content->ptr; - if (file_content->size < header_len + 1) + if (git_buf_len(file_content) < header_len + 1) goto corrupt; /* @@ -174,7 +174,7 @@ static int loose_parse_oid(git_oid *oid, git_buf *file_content) buffer = (char *)file_content->ptr; /* File format: 40 chars (OID) + newline */ - if (file_content->size < GIT_OID_HEXSZ + 1) + if (git_buf_len(file_content) < GIT_OID_HEXSZ + 1) goto corrupt; if (git_oid_fromstr(oid, buffer) < 0) @@ -1484,6 +1484,7 @@ int git_reference_foreach( if (list_flags & GIT_REF_PACKED) { const char *ref_name; void *ref; + GIT_UNUSED(ref); if (packed_load(repo) < 0) return -1; diff --git a/src/refspec.c b/src/refspec.c index ab0108b8c..bec770a30 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -104,10 +104,10 @@ int git_refspec_transform_r(git_buf *out, const git_refspec *spec, const char *n * No '*' at the end means that it's mapped to one specific local * branch, so no actual transformation is needed. */ - if (out->size > 0 && out->ptr[out->size - 1] != '*') + if (git_buf_len(out) > 0 && out->ptr[git_buf_len(out) - 1] != '*') return 0; - git_buf_truncate(out, out->size - 1); /* remove trailing '*' */ + git_buf_truncate(out, git_buf_len(out) - 1); /* remove trailing '*' */ git_buf_puts(out, name + strlen(spec->src) - 1); if (git_buf_oom(out)) diff --git a/src/remote.c b/src/remote.c index 71cb62719..98c256929 100644 --- a/src/remote.c +++ b/src/remote.c @@ -381,13 +381,8 @@ void git_remote_disconnect(git_remote *remote) { assert(remote); - if (remote->transport != NULL) { - if (remote->transport->connected) + if (remote->transport != NULL && remote->transport->connected) remote->transport->close(remote->transport); - - remote->transport->free(remote->transport); - remote->transport = NULL; - } } void git_remote_free(git_remote *remote) @@ -395,14 +390,21 @@ void git_remote_free(git_remote *remote) if (remote == NULL) return; + if (remote->transport != NULL) { + git_remote_disconnect(remote); + + remote->transport->free(remote->transport); + remote->transport = NULL; + } + + git_vector_free(&remote->refs); + git__free(remote->fetch.src); git__free(remote->fetch.dst); git__free(remote->push.src); git__free(remote->push.dst); git__free(remote->url); git__free(remote->name); - git_vector_free(&remote->refs); - git_remote_disconnect(remote); git__free(remote); } diff --git a/src/repository.c b/src/repository.c index affc0c4c1..cfabee420 100644 --- a/src/repository.c +++ b/src/repository.c @@ -278,7 +278,7 @@ static int find_repo( if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0) return error; - while (!error && !repo_path->size) { + while (!error && !git_buf_len(repo_path)) { if (p_stat(path.ptr, &st) == 0) { /* check that we have not crossed device boundaries */ if (initial_device == 0) @@ -328,7 +328,7 @@ static int find_repo( } if (!error && parent_path != NULL) { - if (!repo_path->size) + if (!git_buf_len(repo_path)) git_buf_clear(parent_path); else { git_path_dirname_r(parent_path, path.ptr); @@ -340,7 +340,7 @@ static int find_repo( git_buf_free(&path); - if (!repo_path->size && !error) { + if (!git_buf_len(repo_path) && !error) { giterr_set(GITERR_REPOSITORY, "Could not find repository from '%s'", start_path); error = GIT_ENOTFOUND; diff --git a/src/revwalk.c b/src/revwalk.c index 4f2f82798..c62bb4e0e 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -141,7 +141,7 @@ static commit_object **alloc_parents( return (commit_object **)((char *)commit + sizeof(commit_object)); return (commit_object **)git_pool_malloc( - &walk->commit_pool, n_parents * sizeof(commit_object *)); + &walk->commit_pool, (uint32_t)(n_parents * sizeof(commit_object *))); } diff --git a/src/transports/http.c b/src/transports/http.c index 012e8ffbc..3690f3ded 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -165,6 +165,12 @@ static int on_headers_complete(http_parser *parser) transport_http *t = (transport_http *) parser->data; git_buf *buf = &t->buf; + /* The content-type is text/plain for 404, so don't validate */ + if (parser->status_code == 404) { + git_buf_clear(buf); + return 0; + } + if (t->content_type == NULL) { t->content_type = git__strdup(git_buf_cstr(buf)); if (t->content_type == NULL) @@ -187,6 +193,10 @@ static int on_body_store_refs(http_parser *parser, const char *str, size_t len) { transport_http *t = (transport_http *) parser->data; + if (parser->status_code == 404) { + return git_buf_put(&t->buf, str, len); + } + return git_protocol_store_refs(&t->proto, str, len); } @@ -195,6 +205,12 @@ static int on_message_complete(http_parser *parser) transport_http *t = (transport_http *) parser->data; t->transfer_finished = 1; + + if (parser->status_code == 404) { + giterr_set(GITERR_NET, "Remote error: %s", git_buf_cstr(&t->buf)); + t->error = -1; + } + return 0; } @@ -321,7 +337,7 @@ static int on_body_parse_response(http_parser *parser, const char *str, size_t l const char *line_end, *ptr; if (len == 0) { /* EOF */ - if (buf->size != 0) { + if (git_buf_len(buf) != 0) { giterr_set(GITERR_NET, "Unexpected EOF"); return t->error = -1; } else { @@ -334,10 +350,10 @@ static int on_body_parse_response(http_parser *parser, const char *str, size_t l while (1) { git_pkt *pkt; - if (buf->size == 0) + if (git_buf_len(buf) == 0) return 0; - error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->size); + error = git_pkt_parse_line(&pkt, ptr, &line_end, git_buf_len(buf)); if (error == GIT_ESHORTBUFFER) { return 0; /* Ask for more */ } @@ -555,9 +571,9 @@ static int http_download_pack(git_transport *transport, git_repository *repo, gi memset(&settings, 0x0, sizeof(settings)); settings.on_message_complete = on_message_complete_download_pack; settings.on_body = on_body_download_pack; - *bytes = oldbuf->size; + *bytes = git_buf_len(oldbuf); - if (git_indexer_stream_add(idx, oldbuf->ptr, oldbuf->size, stats) < 0) + if (git_indexer_stream_add(idx, git_buf_cstr(oldbuf), git_buf_len(oldbuf), stats) < 0) goto on_error; do { diff --git a/src/tree.c b/src/tree.c index 62b613d71..90b054dd8 100644 --- a/src/tree.c +++ b/src/tree.c @@ -705,7 +705,7 @@ static int tree_walk_post( if (entry_is_tree(entry)) { git_tree *subtree; - size_t path_len = path->size; + size_t path_len = git_buf_len(path); if ((error = git_tree_lookup( &subtree, tree->object.repo, &entry->oid)) < 0) |
