summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attr.c34
-rw-r--r--src/attr_file.c54
-rw-r--r--src/attr_file.h6
-rw-r--r--src/buffer.h7
-rw-r--r--src/config_file.c2
-rw-r--r--src/crlf.c4
-rw-r--r--src/diff.c3
-rw-r--r--src/diff_output.c35
-rw-r--r--src/filter.c10
-rw-r--r--src/ignore.c9
-rw-r--r--src/indexer.c6
-rw-r--r--src/khash.h16
-rw-r--r--src/odb_loose.c16
-rw-r--r--src/odb_pack.c2
-rw-r--r--src/path.c14
-rw-r--r--src/pkt.c35
-rw-r--r--src/pkt.h6
-rw-r--r--src/pool.c12
-rw-r--r--src/protocol.c13
-rw-r--r--src/refs.c5
-rw-r--r--src/refspec.c4
-rw-r--r--src/remote.c18
-rw-r--r--src/repository.c6
-rw-r--r--src/revwalk.c2
-rw-r--r--src/transports/http.c26
-rw-r--r--src/tree.c2
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);
diff --git a/src/pkt.c b/src/pkt.c
index 2c9fe27da..00836bc34 100644
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -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);
diff --git a/src/pkt.h b/src/pkt.h
index 7e696f70f..75442c833 100644
--- a/src/pkt.h
+++ b/src/pkt.h
@@ -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)