summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/errors.h3
-rw-r--r--src/blob.c2
-rw-r--r--src/errors.c28
-rw-r--r--src/filebuf.c8
-rw-r--r--src/filebuf.h1
-rw-r--r--src/fileops.c10
-rw-r--r--src/indexer.c12
-rw-r--r--src/map.h2
-rw-r--r--src/mwindow.c15
-rw-r--r--src/object.c2
-rw-r--r--src/odb.c113
-rw-r--r--src/odb.h10
-rw-r--r--src/odb_loose.c323
-rw-r--r--src/odb_pack.c158
-rw-r--r--src/pack.c280
-rw-r--r--src/pack.h12
-rw-r--r--src/refs.c4
-rw-r--r--src/unix/map.c31
-rw-r--r--src/win32/map.c53
-rw-r--r--src/win32/posix_w32.c4
-rw-r--r--tests-clar/attr/attr_expect.h2
21 files changed, 496 insertions, 577 deletions
diff --git a/include/git2/errors.h b/include/git2/errors.h
index 085dd52f0..cd9dc08e7 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -103,7 +103,7 @@ typedef enum {
GIT_EOBJCORRUPTED = -28,
/** The given short oid is ambiguous */
- GIT_EAMBIGUOUSOIDPREFIX = -29,
+ GIT_EAMBIGUOUS = -29,
/** Skip and passthrough the given ODB backend */
GIT_EPASSTHROUGH = -30,
@@ -128,6 +128,7 @@ typedef enum {
GITERR_REPOSITORY,
GITERR_CONFIG,
GITERR_REGEX,
+ GITERR_ODB
} git_error_class;
/**
diff --git a/src/blob.c b/src/blob.c
index b67f8afa5..60a6b55d6 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -78,7 +78,7 @@ static int write_file_stream(git_oid *oid, git_odb *odb, const char *path, git_o
char buffer[4096];
git_odb_stream *stream = NULL;
- if ((error = git_odb_open_wstream(&stream, odb, file_size, GIT_OBJ_BLOB)) < GIT_SUCCESS)
+ if ((error = git_odb_open_wstream(&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < GIT_SUCCESS)
return error;
if ((fd = p_open(path, O_RDONLY)) < 0) {
diff --git a/src/errors.c b/src/errors.c
index 6fb7777f0..19bc7b77b 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -40,7 +40,7 @@ static struct {
{GIT_EEXISTS, "A reference with this name already exists"},
{GIT_EOVERFLOW, "The given integer literal is too large to be parsed"},
{GIT_ENOTNUM, "The given literal is not a valid number"},
- {GIT_EAMBIGUOUSOIDPREFIX, "The given oid prefix is ambiguous"},
+ {GIT_EAMBIGUOUS, "The given oid prefix is ambiguous"},
};
const char *git_strerror(int num)
@@ -129,9 +129,29 @@ void giterr_set(int error_class, const char *string, ...)
/* automatically suffix strerror(errno) for GITERR_OS errors */
if (error_class == GITERR_OS) {
- strncat(error_str, ": ", sizeof(error_str));
- strncat(error_str, strerror(errno), sizeof(error_str));
- errno = 0;
+ if (errno != 0) {
+ strncat(error_str, ": ", sizeof(error_str));
+ strncat(error_str, strerror(errno), sizeof(error_str));
+ errno = 0;
+ }
+#ifdef GIT_WIN32
+ else {
+ LPVOID lpMsgBuf;
+ DWORD dw = GetLastError();
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, dw, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
+
+ if (lpMsgBuf) {
+ strncat(error_str, ": ", sizeof(error_str));
+ strncat(error_str, (const char *)lpMsgBuf, sizeof(error_str));
+ LocalFree(lpMsgBuf);
+ }
+ }
+#endif
}
giterr_set_str(error_class, error_str);
diff --git a/src/filebuf.c b/src/filebuf.c
index 5e206c5d8..09b1e0e59 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -67,6 +67,8 @@ static int lock_file(git_filebuf *file, int flags)
if (file->fd < 0)
return -1;
+ file->fd_is_open = true;
+
if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) {
git_file source;
char buffer[2048];
@@ -94,10 +96,10 @@ static int lock_file(git_filebuf *file, int flags)
void git_filebuf_cleanup(git_filebuf *file)
{
- if (file->fd >= 0)
+ if (file->fd_is_open && file->fd >= 0)
p_close(file->fd);
- if (file->fd >= 0 && file->path_lock && git_path_exists(file->path_lock) == true)
+ if (file->fd_is_open && file->path_lock && git_path_exists(file->path_lock))
p_unlink(file->path_lock);
if (file->digest)
@@ -239,6 +241,7 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags)
git_buf_free(&tmp_path);
goto cleanup;
}
+ file->fd_is_open = true;
/* No original path */
file->path_original = NULL;
@@ -308,6 +311,7 @@ int git_filebuf_commit(git_filebuf *file, mode_t mode)
p_close(file->fd);
file->fd = -1;
+ file->fd_is_open = false;
if (p_chmod(file->path_lock, mode)) {
giterr_set(GITERR_OS, "Failed to set attributes for file at '%s'", file->path_lock);
diff --git a/src/filebuf.h b/src/filebuf.h
index 5f9d4ad9d..19e17975b 100644
--- a/src/filebuf.h
+++ b/src/filebuf.h
@@ -40,6 +40,7 @@ struct git_filebuf {
size_t buf_size, buf_pos;
git_file fd;
+ bool fd_is_open;
int last_error;
};
diff --git a/src/fileops.c b/src/fileops.c
index c9fd2c5bc..0ce48828b 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -117,7 +117,7 @@ int git_futils_readbuffer_updated(git_buf *buf, const char *path, time_t *mtime,
return fd;
if (p_fstat(fd, &st) < 0 || S_ISDIR(st.st_mode) || !git__is_sizet(st.st_size+1)) {
- close(fd);
+ p_close(fd);
giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path);
return -1;
}
@@ -127,7 +127,7 @@ int git_futils_readbuffer_updated(git_buf *buf, const char *path, time_t *mtime,
* has been modified.
*/
if (mtime != NULL && *mtime >= st.st_mtime) {
- close(fd);
+ p_close(fd);
return 0;
}
@@ -139,8 +139,8 @@ int git_futils_readbuffer_updated(git_buf *buf, const char *path, time_t *mtime,
git_buf_clear(buf);
if (git_buf_grow(buf, len + 1) < 0) {
- close(fd);
- return GIT_ENOMEM;
+ p_close(fd);
+ return -1;
}
buf->ptr[len] = '\0';
@@ -149,7 +149,7 @@ int git_futils_readbuffer_updated(git_buf *buf, const char *path, time_t *mtime,
ssize_t read_size = p_read(fd, buf->ptr, len);
if (read_size < 0) {
- close(fd);
+ p_close(fd);
giterr_set(GITERR_OS, "Failed to read descriptor for '%s'", path);
return -1;
}
diff --git a/src/indexer.c b/src/indexer.c
index dd7c71962..da6495f90 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -307,7 +307,7 @@ cleanup:
int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
{
git_mwindow_file *mwf;
- off_t off = sizeof(struct git_pack_header);
+ git_off_t off = sizeof(struct git_pack_header);
int error;
struct entry *entry;
unsigned int left, processed;
@@ -328,18 +328,18 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
struct git_pack_entry *pentry;
git_mwindow *w = NULL;
int i;
- off_t entry_start = off;
+ git_off_t entry_start = off;
void *packed;
size_t entry_size;
- entry = git__malloc(sizeof(struct entry));
- memset(entry, 0x0, sizeof(struct entry));
+ entry = git__calloc(1, sizeof(*entry));
+ GITERR_CHECK_ALLOC(entry);
if (off > UINT31_MAX) {
entry->offset = UINT32_MAX;
entry->offset_long = off;
} else {
- entry->offset = off;
+ entry->offset = (uint32_t)off;
}
error = git_packfile_unpack(&obj, idx->pack, &off);
@@ -369,7 +369,7 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
git_oid_cpy(&entry->oid, &oid);
entry->crc = crc32(0L, Z_NULL, 0);
- entry_size = off - entry_start;
+ entry_size = (size_t)(off - entry_start);
packed = git_mwindow_open(mwf, &w, entry_start, entry_size, &left);
if (packed == NULL) {
error = git__rethrow(error, "Failed to open window to read packed data");
diff --git a/src/map.h b/src/map.h
index 0b070fa15..d0ca1ee56 100644
--- a/src/map.h
+++ b/src/map.h
@@ -31,6 +31,8 @@ typedef struct { /* memory mapped buffer */
#endif
} git_map;
+extern int validate_map_args(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset);
+
extern int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offset);
extern int p_munmap(git_map *map);
diff --git a/src/mwindow.c b/src/mwindow.c
index 39f6aeacc..e3de0709c 100644
--- a/src/mwindow.c
+++ b/src/mwindow.c
@@ -178,8 +178,10 @@ static git_mwindow *new_window(
* window.
*/
- if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < GIT_SUCCESS)
- goto cleanup;
+ if (git_futils_mmap_ro(&w->window_map, fd, w->offset, (size_t)len) < 0) {
+ git__free(w);
+ return NULL;
+ }
ctl->mmap_calls++;
ctl->open_windows++;
@@ -191,10 +193,6 @@ static git_mwindow *new_window(
ctl->peak_open_windows = ctl->open_windows;
return w;
-
-cleanup:
- git__free(w);
- return NULL;
}
/*
@@ -253,11 +251,10 @@ unsigned char *git_mwindow_open(
int git_mwindow_file_register(git_mwindow_file *mwf)
{
git_mwindow_ctl *ctl = &GIT_GLOBAL->mem_ctl;
- int error;
if (ctl->windowfiles.length == 0 &&
- (error = git_vector_init(&ctl->windowfiles, 8, NULL)) < GIT_SUCCESS)
- return error;
+ git_vector_init(&ctl->windowfiles, 8, NULL) < 0)
+ return -1;
return git_vector_insert(&ctl->windowfiles, mwf);
}
diff --git a/src/object.c b/src/object.c
index 043001599..bb27f71c1 100644
--- a/src/object.c
+++ b/src/object.c
@@ -92,7 +92,7 @@ int git_object_lookup_prefix(
assert(repo && object_out && id);
if (len < GIT_OID_MINPREFIXLEN)
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX,
+ return git__throw(GIT_EAMBIGUOUS,
"Failed to lookup object. Prefix length is lower than %d.", GIT_OID_MINPREFIXLEN);
error = git_repository_odb__weakptr(&odb, repo);
diff --git a/src/odb.c b/src/odb.c
index edb9c72a0..782a77dc4 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -188,7 +188,7 @@ int git_odb_hashfile(git_oid *out, const char *path, git_otype type)
git_off_t size;
int result, fd = git_futils_open_ro(path);
if (fd < 0)
- return -1;
+ return fd;
if ((size = git_futils_filesize(fd)) < 0 || !git__is_sizet(size)) {
giterr_set(GITERR_OS, "File size overflow for 32-bit systems");
@@ -507,23 +507,20 @@ int git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git
error = b->read_header(len_p, type_p, b, id);
}
- if (error == GIT_EPASSTHROUGH)
+ if (!error || error == GIT_EPASSTHROUGH)
return 0;
/*
* no backend could read only the header.
* try reading the whole object and freeing the contents
*/
- if (error < 0) {
- if ((error = git_odb_read(&object, db, id)) < GIT_SUCCESS)
- return error; /* error already set - pass through */
-
- *len_p = object->raw.len;
- *type_p = object->raw.type;
- git_odb_object_free(object);
- }
+ if ((error = git_odb_read(&object, db, id)) < 0)
+ return error; /* error already set - pass along */
- return GIT_SUCCESS;
+ *len_p = object->raw.len;
+ *type_p = object->raw.type;
+ git_odb_object_free(object);
+ return 0;
}
int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
@@ -536,7 +533,7 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
*out = git_cache_get(&db->cache, id);
if (*out != NULL)
- return GIT_SUCCESS;
+ return 0;
for (i = 0; i < db->backends.length && error < 0; ++i) {
backend_internal *internal = git_vector_get(&db->backends, i);
@@ -546,15 +543,15 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
error = b->read(&raw.data, &raw.len, &raw.type, b, id);
}
- if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS) {
- *out = git_cache_try_store(&db->cache, new_odb_object(id, &raw));
- return GIT_SUCCESS;
- }
+ if (error && error != GIT_EPASSTHROUGH)
+ return error;
- return git__rethrow(error, "Failed to read object");
+ *out = git_cache_try_store(&db->cache, new_odb_object(id, &raw));
+ return 0;
}
-int git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, unsigned int len)
+int git_odb_read_prefix(
+ git_odb_object **out, git_odb *db, const git_oid *short_id, unsigned int len)
{
unsigned int i;
int error = GIT_ENOTFOUND;
@@ -565,7 +562,7 @@ int git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_
assert(out && db);
if (len < GIT_OID_MINPREFIXLEN)
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to lookup object. Prefix length is lower than %d.", GIT_OID_MINPREFIXLEN);
+ return git_odb__error_ambiguous("prefix length too short");
if (len > GIT_OID_HEXSZ)
len = GIT_OID_HEXSZ;
@@ -573,7 +570,7 @@ int git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_
if (len == GIT_OID_HEXSZ) {
*out = git_cache_get(&db->cache, short_id);
if (*out != NULL)
- return GIT_SUCCESS;
+ return 0;
}
for (i = 0; i < db->backends.length && found < 2; ++i) {
@@ -582,33 +579,24 @@ int git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_
if (b->read != NULL) {
error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, short_id, len);
- switch (error) {
- case GIT_SUCCESS:
+ if (!error)
found++;
- break;
- case GIT_ENOTFOUND:
- case GIT_EPASSTHROUGH:
- break;
- case GIT_EAMBIGUOUSOIDPREFIX:
- return git__rethrow(error, "Failed to read object. Ambiguous sha1 prefix");
- default:
- return git__rethrow(error, "Failed to read object");
- }
+ else if (error != GIT_ENOTFOUND && error != GIT_EPASSTHROUGH)
+ return error;
}
}
- if (found == 1) {
- *out = git_cache_try_store(&db->cache, new_odb_object(&full_oid, &raw));
- } else if (found > 1) {
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to read object. Ambiguous sha1 prefix");
- } else {
- return git__throw(GIT_ENOTFOUND, "Failed to read object. Object not found");
- }
+ if (found == 0)
+ return git_odb__error_notfound("no match for prefix");
+ if (found > 1)
+ return git_odb__error_ambiguous("multiple matches for prefix");
- return GIT_SUCCESS;
+ *out = git_cache_try_store(&db->cache, new_odb_object(&full_oid, &raw));
+ return 0;
}
-int git_odb_write(git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
+int git_odb_write(
+ git_oid *oid, git_odb *db, const void *data, size_t len, git_otype type)
{
unsigned int i;
int error = GIT_ERROR;
@@ -628,24 +616,25 @@ int git_odb_write(git_oid *oid, git_odb *db, const void *data, size_t len, git_o
error = b->write(oid, b, data, len, type);
}
- if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS)
- return GIT_SUCCESS;
+ if (!error || error == GIT_EPASSTHROUGH)
+ return 0;
/* if no backends were able to write the object directly, we try a streaming
* write to the backends; just write the whole object into the stream in one
* push */
- if ((error = git_odb_open_wstream(&stream, db, len, type)) == GIT_SUCCESS) {
- stream->write(stream, data, len);
- error = stream->finalize_write(oid, stream);
- stream->free(stream);
- return GIT_SUCCESS;
- }
+ if ((error = git_odb_open_wstream(&stream, db, len, type)) != 0)
+ return error;
- return git__rethrow(error, "Failed to write object");
+ stream->write(stream, data, len);
+ error = stream->finalize_write(oid, stream);
+ stream->free(stream);
+
+ return error;
}
-int git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
+int git_odb_open_wstream(
+ git_odb_stream **stream, git_odb *db, size_t size, git_otype type)
{
unsigned int i;
int error = GIT_ERROR;
@@ -666,10 +655,10 @@ int git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_
error = init_fake_wstream(stream, b, size, type);
}
- if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS)
- return GIT_SUCCESS;
+ if (error == GIT_EPASSTHROUGH)
+ error = 0;
- return git__rethrow(error, "Failed to open write stream");
+ return error;
}
int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid)
@@ -687,9 +676,21 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi
error = b->readstream(stream, b, oid);
}
- if (error == GIT_EPASSTHROUGH || error == GIT_SUCCESS)
- return GIT_SUCCESS;
+ if (error == GIT_EPASSTHROUGH)
+ error = 0;
- return git__rethrow(error, "Failed to open read stream");
+ return error;
+}
+
+int git_odb__error_notfound(const char *message)
+{
+ giterr_set(GITERR_ODB, "Object not found - %s", message);
+ return GIT_ENOTFOUND;
+}
+
+int git_odb__error_ambiguous(const char *message)
+{
+ giterr_set(GITERR_ODB, "Ambiguous SHA1 prefix - %s", message);
+ return GIT_EAMBIGUOUS;
}
diff --git a/src/odb.h b/src/odb.h
index 2f84ebea4..4c425c007 100644
--- a/src/odb.h
+++ b/src/odb.h
@@ -67,4 +67,14 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type);
*/
int git_odb__hashlink(git_oid *out, const char *path);
+/*
+ * Generate a GIT_ENOTFOUND error for the ODB.
+ */
+int git_odb__error_notfound(const char *message);
+
+/*
+ * Generate a GIT_EAMBIGUOUS error for the ODB.
+ */
+int git_odb__error_ambiguous(const char *message);
+
#endif
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 17fede4a3..c493cc60b 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -61,8 +61,8 @@ 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) < GIT_SUCCESS)
- return GIT_ENOMEM;
+ if (git_buf_grow(name, name->size + GIT_OID_HEXSZ + 3) < 0)
+ return -1;
git_path_to_dir(name);
@@ -71,7 +71,7 @@ static int object_file_name(git_buf *name, const char *dir, const git_oid *id)
name->size += GIT_OID_HEXSZ + 1;
name->ptr[name->size] = '\0';
- return GIT_SUCCESS;
+ return 0;
}
@@ -199,10 +199,12 @@ static int finish_inflate(z_stream *s)
inflateEnd(s);
- if ((status != Z_STREAM_END) || (s->avail_in != 0))
- return git__throw(GIT_ERROR, "Failed to finish inflation. Stream aborted prematurely");
+ if ((status != Z_STREAM_END) || (s->avail_in != 0)) {
+ giterr_set(GITERR_ZLIB, "Failed to finish ZLib inflation. Stream aborted prematurely");
+ return -1;
+ }
- return GIT_SUCCESS;
+ return 0;
}
static int is_zlib_compressed_data(unsigned char *data)
@@ -226,21 +228,24 @@ static int inflate_buffer(void *in, size_t inlen, void *out, size_t outlen)
zs.next_in = in;
zs.avail_in = (uInt)inlen;
- if (inflateInit(&zs) < Z_OK)
- return git__throw(GIT_ERROR, "Failed to inflate buffer");
+ if (inflateInit(&zs) < Z_OK) {
+ giterr_set(GITERR_ZLIB, "Failed to inflate buffer");
+ return -1;
+ }
while (status == Z_OK)
status = inflate(&zs, Z_FINISH);
inflateEnd(&zs);
- if ((status != Z_STREAM_END) /*|| (zs.avail_in != 0) */)
- return git__throw(GIT_ERROR, "Failed to inflate buffer. Stream aborted prematurely");
-
- if (zs.total_out != outlen)
- return git__throw(GIT_ERROR, "Failed to inflate buffer. Stream aborted prematurely");
+ if (status != Z_STREAM_END /* || zs.avail_in != 0 */ ||
+ zs.total_out != outlen)
+ {
+ giterr_set(GITERR_ZLIB, "Failed to inflate buffer. Stream aborted prematurely");
+ return -1;
+ }
- return GIT_SUCCESS;
+ return 0;
}
static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
@@ -297,24 +302,23 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
* read the object header, which is an (uncompressed)
* binary encoding of the object type and size.
*/
- if ((used = get_binary_object_header(&hdr, obj)) == 0)
- return git__throw(GIT_ERROR, "Failed to inflate loose object. Object has no header");
-
- if (!git_object_typeisloose(hdr.type))
- return git__throw(GIT_ERROR, "Failed to inflate loose object. Wrong object type");
+ if ((used = get_binary_object_header(&hdr, obj)) == 0 ||
+ !git_object_typeisloose(hdr.type)) {
+ giterr_set(GITERR_ODB, "Failed to inflate loose object.");
+ return -1;
+ }
/*
* allocate a buffer and inflate the data into it
*/
buf = git__malloc(hdr.size + 1);
- if (!buf)
- return GIT_ENOMEM;
+ GITERR_CHECK_ALLOC(buf);
in = ((unsigned char *)obj->ptr) + used;
len = obj->size - used;
- if (inflate_buffer(in, len, buf, hdr.size)) {
+ if (inflate_buffer(in, len, buf, hdr.size) < 0) {
git__free(buf);
- return git__throw(GIT_ERROR, "Failed to inflate loose object. Could not inflate buffer");
+ return -1;
}
buf[hdr.size] = '\0';
@@ -322,7 +326,7 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
out->len = hdr.size;
out->type = hdr.type;
- return GIT_SUCCESS;
+ return 0;
}
static int inflate_disk_obj(git_rawobj *out, git_buf *obj)
@@ -342,28 +346,27 @@ static int inflate_disk_obj(git_rawobj *out, git_buf *obj)
* inflate the initial part of the io buffer in order
* to parse the object header (type and size).
*/
- if (start_inflate(&zs, obj, head, sizeof(head)) < Z_OK)
- return git__throw(GIT_ERROR, "Failed to inflate disk object. Could not inflate buffer");
-
- if ((used = get_object_header(&hdr, head)) == 0)
- return git__throw(GIT_ERROR, "Failed to inflate disk object. Object has no header");
-
- if (!git_object_typeisloose(hdr.type))
- return git__throw(GIT_ERROR, "Failed to inflate disk object. Wrong object type");
+ if (start_inflate(&zs, obj, head, sizeof(head)) < Z_OK ||
+ (used = get_object_header(&hdr, head)) == 0 ||
+ !git_object_typeisloose(hdr.type))
+ {
+ giterr_set(GITERR_ODB, "Failed to inflate disk object.");
+ return -1;
+ }
/*
* allocate a buffer and inflate the object data into it
* (including the initial sequence in the head buffer).
*/
if ((buf = inflate_tail(&zs, head, used, &hdr)) == NULL)
- return GIT_ENOMEM;
+ return -1;
buf[hdr.size] = '\0';
out->data = buf;
out->len = hdr.size;
out->type = hdr.type;
- return GIT_SUCCESS;
+ return 0;
}
@@ -388,24 +391,23 @@ static int read_loose(git_rawobj *out, git_buf *loc)
assert(out && loc);
if (git_buf_oom(loc))
- return GIT_ENOMEM;
+ return -1;
out->data = NULL;
out->len = 0;
out->type = GIT_OBJ_BAD;
- if (git_futils_readbuffer(&obj, loc->ptr) < 0)
- return git__throw(GIT_ENOTFOUND, "Failed to read loose object. File not found");
+ if (!(error = git_futils_readbuffer(&obj, loc->ptr)))
+ error = inflate_disk_obj(out, &obj);
- error = inflate_disk_obj(out, &obj);
git_buf_free(&obj);
- return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to read loose object");
+ return error;
}
static int read_header_loose(git_rawobj *out, git_buf *loc)
{
- int error = GIT_SUCCESS, z_return = Z_ERRNO, read_bytes;
+ int error = 0, z_return = Z_ERRNO, read_bytes;
git_file fd;
z_stream zs;
obj_hdr header_obj;
@@ -414,48 +416,40 @@ static int read_header_loose(git_rawobj *out, git_buf *loc)
assert(out && loc);
if (git_buf_oom(loc))
- return GIT_ENOMEM;
+ return -1;
out->data = NULL;
- if ((fd = p_open(loc->ptr, O_RDONLY)) < 0)
- return git__throw(GIT_ENOTFOUND, "Failed to read loose object header. File not found");
+ if ((fd = git_futils_open_ro(loc->ptr)) < 0)
+ return fd;
init_stream(&zs, inflated_buffer, sizeof(inflated_buffer));
- if (inflateInit(&zs) < Z_OK) {
- error = GIT_EZLIB;
- goto cleanup;
- }
+ z_return = inflateInit(&zs);
- do {
- if ((read_bytes = read(fd, raw_buffer, sizeof(raw_buffer))) > 0) {
+ while (z_return == Z_OK) {
+ if ((read_bytes = p_read(fd, raw_buffer, sizeof(raw_buffer))) > 0) {
set_stream_input(&zs, raw_buffer, read_bytes);
z_return = inflate(&zs, 0);
- } else {
+ } else
z_return = Z_STREAM_END;
- break;
- }
- } while (z_return == Z_OK);
+ }
if ((z_return != Z_STREAM_END && z_return != Z_BUF_ERROR)
|| get_object_header(&header_obj, inflated_buffer) == 0
- || git_object_typeisloose(header_obj.type) == 0) {
- error = GIT_EOBJCORRUPTED;
- goto cleanup;
+ || git_object_typeisloose(header_obj.type) == 0)
+ {
+ giterr_set(GITERR_ZLIB, "Failed to read loose object header");
+ error = -1;
+ } else {
+ out->len = header_obj.size;
+ out->type = header_obj.type;
}
- out->len = header_obj.size;
- out->type = header_obj.type;
-
-cleanup:
finish_inflate(&zs);
p_close(fd);
- if (error < GIT_SUCCESS)
- return git__throw(error, "Failed to read loose object header. Header is corrupted");
-
- return GIT_SUCCESS;
+ return error;
}
static int locate_object(
@@ -465,8 +459,8 @@ static int locate_object(
{
int error = object_file_name(object_location, backend->objects_dir, oid);
- if (error == GIT_SUCCESS)
- error = git_path_exists(git_buf_cstr(object_location)) ? GIT_SUCCESS : GIT_ENOTFOUND;
+ if (!error && !git_path_exists(object_location->ptr))
+ return GIT_ENOTFOUND;
return error;
}
@@ -477,7 +471,7 @@ static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) {
if (pathbuf->size - sstate->dir_len != GIT_OID_HEXSZ - 2) {
/* Entry cannot be an object. Continue to next entry */
- return GIT_SUCCESS;
+ return 0;
}
if (git_path_isdir(pathbuf->ptr) == false) {
@@ -495,10 +489,11 @@ static int fn_locate_object_short_oid(void *state, git_buf *pathbuf) {
sstate->found++;
}
}
+
if (sstate->found > 1)
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Ambiguous sha1 prefix within loose objects");
+ return git_odb__error_ambiguous("multiple matches in loose objects");
- return GIT_SUCCESS;
+ return 0;
}
/* Locate an object matching a given short oid */
@@ -515,8 +510,8 @@ static int locate_object_short_oid(
int error;
/* prealloc memory for OBJ_DIR/xx/ */
- if ((error = git_buf_grow(object_location, dir_len + 5)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to locate object from short oid");
+ if (git_buf_grow(object_location, dir_len + 5) < 0)
+ return -1;
git_buf_sets(object_location, objects_dir);
git_path_to_dir(object_location);
@@ -528,46 +523,43 @@ static int locate_object_short_oid(
git_oid_fmt((char *)state.short_oid, short_oid);
/* Explore OBJ_DIR/xx/ where xx is the beginning of hex formatted short oid */
- error = git_buf_printf(object_location, "%.2s/", state.short_oid);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to locate object from short oid");
+ if (git_buf_printf(object_location, "%.2s/", state.short_oid) < 0)
+ return -1;
/* Check that directory exists */
if (git_path_isdir(object_location->ptr) == false)
- return git__throw(GIT_ENOTFOUND, "Failed to locate object from short oid. Object not found");
+ return git_odb__error_notfound("failed to locate from short oid");
state.dir_len = object_location->size;
state.short_oid_len = len;
state.found = 0;
/* Explore directory to find a unique object matching short_oid */
- error = git_path_direach(object_location, fn_locate_object_short_oid, &state);
+ error = git_path_direach(
+ object_location, fn_locate_object_short_oid, &state);
if (error)
- return git__rethrow(error, "Failed to locate object from short oid");
+ return error;
- if (!state.found) {
- return git__throw(GIT_ENOTFOUND, "Failed to locate object from short oid. Object not found");
- }
+ if (!state.found)
+ return git_odb__error_notfound("failed to locate from short oid");
/* Convert obtained hex formatted oid to raw */
error = git_oid_fromstr(res_oid, (char *)state.res_oid);
- if (error) {
- return git__rethrow(error, "Failed to locate object from short oid");
- }
+ if (error)
+ return error;
/* Update the location according to the oid obtained */
git_buf_truncate(object_location, dir_len);
- error = git_buf_grow(object_location, dir_len + GIT_OID_HEXSZ + 2);
- if (error)
- return git__rethrow(error, "Failed to locate object from short oid");
+ if (git_buf_grow(object_location, dir_len + GIT_OID_HEXSZ + 2) < 0)
+ return -1;
git_oid_pathfmt(object_location->ptr + dir_len, res_oid);
object_location->size += GIT_OID_HEXSZ + 1;
object_location->ptr[object_location->size] = '\0';
- return GIT_SUCCESS;
+ return 0;
}
@@ -598,8 +590,8 @@ static int loose_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_
raw.type = GIT_OBJ_BAD;
if (locate_object(&object_path, (loose_backend *)backend, oid) < 0)
- error = git__throw(GIT_ENOTFOUND, "Failed to read loose backend header. Object not found");
- else if ((error = read_header_loose(&raw, &object_path)) == GIT_SUCCESS) {
+ error = git_odb__error_notfound("in loose backend");
+ else if ((error = read_header_loose(&raw, &object_path)) == 0) {
*len_p = raw.len;
*type_p = raw.type;
}
@@ -613,20 +605,17 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p
{
git_buf object_path = GIT_BUF_INIT;
git_rawobj raw;
- int error = GIT_SUCCESS;
+ int error = 0;
assert(backend && oid);
if (locate_object(&object_path, (loose_backend *)backend, oid) < 0)
- error = git__throw(GIT_ENOTFOUND, "Failed to read loose backend. Object not found");
- else if ((error = read_loose(&raw, &object_path)) == GIT_SUCCESS) {
+ error = git_odb__error_notfound("in loose backend");
+ else if ((error = read_loose(&raw, &object_path)) == 0) {
*buffer_p = raw.data;
*len_p = raw.len;
*type_p = raw.type;
}
- else {
- git__rethrow(error, "Failed to read loose backend");
- }
git_buf_free(&object_path);
@@ -642,16 +631,15 @@ static int loose_backend__read_prefix(
const git_oid *short_oid,
unsigned int len)
{
- int error = GIT_SUCCESS;
+ int error = 0;
if (len < GIT_OID_MINPREFIXLEN)
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to read loose "
- "backend. Prefix length is lower than %d.", GIT_OID_MINPREFIXLEN);
+ error = git_odb__error_ambiguous("prefix length too short");
- if (len >= GIT_OID_HEXSZ) {
+ else if (len >= GIT_OID_HEXSZ) {
/* We can fall back to regular read method */
error = loose_backend__read(buffer_p, len_p, type_p, backend, short_oid);
- if (error == GIT_SUCCESS)
+ if (!error)
git_oid_cpy(out_oid, short_oid);
} else {
git_buf object_path = GIT_BUF_INIT;
@@ -660,11 +648,9 @@ static int loose_backend__read_prefix(
assert(backend && short_oid);
if ((error = locate_object_short_oid(&object_path, out_oid,
- (loose_backend *)backend, short_oid, len)) < 0)
- git__rethrow(error, "Failed to read loose backend");
- else if ((error = read_loose(&raw, &object_path)) < GIT_SUCCESS)
- git__rethrow(error, "Failed to read loose backend");
- else {
+ (loose_backend *)backend, short_oid, len)) == 0 &&
+ (error = read_loose(&raw, &object_path)) == 0)
+ {
*buffer_p = raw.data;
*len_p = raw.len;
*type_p = raw.type;
@@ -687,47 +673,33 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
git_buf_free(&object_path);
- return (error == GIT_SUCCESS);
+ return !error;
}
static int loose_backend__stream_fwrite(git_oid *oid, git_odb_stream *_stream)
{
loose_writestream *stream = (loose_writestream *)_stream;
loose_backend *backend = (loose_backend *)_stream->backend;
-
- int error;
git_buf final_path = GIT_BUF_INIT;
+ int error = 0;
- if ((error = git_filebuf_hash(oid, &stream->fbuf)) < GIT_SUCCESS)
- goto cleanup;
-
- if ((error = object_file_name(&final_path, backend->objects_dir, oid)) < GIT_SUCCESS)
- goto cleanup;
-
- if (git_buf_oom(&final_path))
- return GIT_ENOMEM;
-
- if ((error = git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE)) < GIT_SUCCESS)
- goto cleanup;
-
+ if (git_filebuf_hash(oid, &stream->fbuf) < 0 ||
+ object_file_name(&final_path, backend->objects_dir, oid) < 0 ||
+ git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE) < 0)
+ error = -1;
/*
* Don't try to add an existing object to the repository. This
* is what git does and allows us to sidestep the fact that
* we're not allowed to overwrite a read-only file on Windows.
*/
- if (git_path_exists(final_path.ptr) == true) {
+ else if (git_path_exists(final_path.ptr) == true)
git_filebuf_cleanup(&stream->fbuf);
- goto cleanup;
- }
-
- error = git_filebuf_commit_at(&stream->fbuf, final_path.ptr, GIT_OBJECT_FILE_MODE);
+ else
+ error = git_filebuf_commit_at(
+ &stream->fbuf, final_path.ptr, GIT_OBJECT_FILE_MODE);
-cleanup:
git_buf_free(&final_path);
- if (error < GIT_SUCCESS)
- git__rethrow(error, "Failed to write loose backend");
-
return error;
}
@@ -751,22 +723,18 @@ static int format_object_header(char *hdr, size_t n, size_t obj_len, git_otype o
int len = snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len);
assert(len > 0); /* otherwise snprintf() is broken */
- assert(((size_t) len) < n); /* otherwise the caller is broken! */
+ assert(((size_t)len) < n); /* otherwise the caller is broken! */
- if (len < 0 || ((size_t) len) >= n)
- return git__throw(GIT_ERROR, "Failed to format object header. Length is out of bounds");
return len+1;
}
static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_backend, size_t length, git_otype type)
{
loose_backend *backend;
- loose_writestream *stream;
-
+ loose_writestream *stream = NULL;
char hdr[64];
git_buf tmp_path = GIT_BUF_INIT;
int hdrlen;
- int error;
assert(_backend);
@@ -774,12 +742,9 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_
*stream_out = NULL;
hdrlen = format_object_header(hdr, sizeof(hdr), length, type);
- if (hdrlen < GIT_SUCCESS)
- return git__throw(GIT_EOBJCORRUPTED, "Failed to create loose backend stream. Object is corrupted");
stream = git__calloc(1, sizeof(loose_writestream));
- if (stream == NULL)
- return GIT_ENOMEM;
+ GITERR_CHECK_ALLOC(stream);
stream->stream.backend = _backend;
stream->stream.read = NULL; /* read only */
@@ -788,31 +753,21 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_
stream->stream.free = &loose_backend__stream_free;
stream->stream.mode = GIT_STREAM_WRONLY;
- error = git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object");
- if (error < GIT_SUCCESS)
- goto cleanup;
-
- error = git_filebuf_open(&stream->fbuf, tmp_path.ptr,
- GIT_FILEBUF_HASH_CONTENTS |
- GIT_FILEBUF_TEMPORARY |
- (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT));
- if (error < GIT_SUCCESS)
- goto cleanup;
-
- error = stream->stream.write((git_odb_stream *)stream, hdr, hdrlen);
- if (error < GIT_SUCCESS)
- goto cleanup;
-
+ if (git_buf_joinpath(&tmp_path, backend->objects_dir, "tmp_object") < 0 ||
+ git_filebuf_open(&stream->fbuf, tmp_path.ptr,
+ GIT_FILEBUF_HASH_CONTENTS |
+ GIT_FILEBUF_TEMPORARY |
+ (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT)) < 0 ||
+ stream->stream.write((git_odb_stream *)stream, hdr, hdrlen) < 0)
+ {
+ git_filebuf_cleanup(&stream->fbuf);
+ git__free(stream);
+ stream = NULL;
+ }
git_buf_free(&tmp_path);
-
*stream_out = (git_odb_stream *)stream;
- return GIT_SUCCESS;
-cleanup:
- git_buf_free(&tmp_path);
- git_filebuf_cleanup(&stream->fbuf);
- git__free(stream);
- return git__rethrow(error, "Failed to create loose backend stream");
+ return !stream ? -1 : 0;
}
static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const void *data, size_t len, git_otype type)
@@ -826,36 +781,26 @@ static int loose_backend__write(git_oid *oid, git_odb_backend *_backend, const v
backend = (loose_backend *)_backend;
/* prepare the header for the file */
- {
- header_len = format_object_header(header, sizeof(header), len, type);
- if (header_len < GIT_SUCCESS)
- return GIT_EOBJCORRUPTED;
- }
-
- error = git_buf_joinpath(&final_path, backend->objects_dir, "tmp_object");
- if (error < GIT_SUCCESS)
- goto cleanup;
+ header_len = format_object_header(header, sizeof(header), len, type);
- error = git_filebuf_open(&fbuf, final_path.ptr,
- GIT_FILEBUF_HASH_CONTENTS |
- GIT_FILEBUF_TEMPORARY |
- (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT));
- if (error < GIT_SUCCESS)
+ if (git_buf_joinpath(&final_path, backend->objects_dir, "tmp_object") < 0 ||
+ git_filebuf_open(&fbuf, final_path.ptr,
+ GIT_FILEBUF_HASH_CONTENTS |
+ GIT_FILEBUF_TEMPORARY |
+ (backend->object_zlib_level << GIT_FILEBUF_DEFLATE_SHIFT)) < 0)
+ {
+ error = -1;
goto cleanup;
+ }
git_filebuf_write(&fbuf, header, header_len);
git_filebuf_write(&fbuf, data, len);
git_filebuf_hash(oid, &fbuf);
- error = object_file_name(&final_path, backend->objects_dir, oid);
- if (error < GIT_SUCCESS)
- goto cleanup;
-
- error = git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE);
- if (error < GIT_SUCCESS)
- goto cleanup;
-
- error = git_filebuf_commit_at(&fbuf, final_path.ptr, GIT_OBJECT_FILE_MODE);
+ if (object_file_name(&final_path, backend->objects_dir, oid) < 0 ||
+ git_futils_mkpath2file(final_path.ptr, GIT_OBJECT_DIR_MODE) < 0 ||
+ git_filebuf_commit_at(&fbuf, final_path.ptr, GIT_OBJECT_FILE_MODE) < 0)
+ error = -1;
cleanup:
if (error < GIT_SUCCESS)
@@ -883,14 +828,10 @@ int git_odb_backend_loose(
loose_backend *backend;
backend = git__calloc(1, sizeof(loose_backend));
- if (backend == NULL)
- return GIT_ENOMEM;
+ GITERR_CHECK_ALLOC(backend);
backend->objects_dir = git__strdup(objects_dir);
- if (backend->objects_dir == NULL) {
- git__free(backend);
- return GIT_ENOMEM;
- }
+ GITERR_CHECK_ALLOC(backend->objects_dir);
if (compression_level < 0)
compression_level = Z_BEST_SPEED;
@@ -907,5 +848,5 @@ int git_odb_backend_loose(
backend->parent.free = &loose_backend__free;
*backend_out = (git_odb_backend *)backend;
- return GIT_SUCCESS;
+ return 0;
}
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 159c88685..7add3718a 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -137,19 +137,19 @@ static int packfile_load__cb(void *_data, git_buf *path);
static int packfile_refresh_all(struct pack_backend *backend);
static int pack_entry_find(struct git_pack_entry *e,
- struct pack_backend *backend, const git_oid *oid);
+ struct pack_backend *backend, const git_oid *oid);
/* Can find the offset of an object given
* a prefix of an identifier.
- * Throws GIT_EAMBIGUOUSOIDPREFIX if short oid
- * is ambiguous.
+ * Sets GIT_EAMBIGUOUS if short oid is ambiguous.
* This method assumes that len is between
* GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ.
*/
-static int pack_entry_find_prefix(struct git_pack_entry *e,
- struct pack_backend *backend,
- const git_oid *short_oid,
- unsigned int len);
+static int pack_entry_find_prefix(
+ struct git_pack_entry *e,
+ struct pack_backend *backend,
+ const git_oid *short_oid,
+ unsigned int len);
@@ -215,27 +215,22 @@ static int packfile_load__cb(void *_data, git_buf *path)
size_t i;
if (git__suffixcmp(path->ptr, ".idx") != 0)
- return GIT_SUCCESS; /* not an index */
+ return 0; /* not an index */
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)
- return GIT_SUCCESS;
+ return 0;
}
error = git_packfile_check(&pack, path->ptr);
- if (error == GIT_ENOTFOUND) {
+ if (error == GIT_ENOTFOUND)
/* ignore missing .pack file as git does */
return GIT_SUCCESS;
- } else if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to load packfile");
-
- if (git_vector_insert(&backend->packs, pack) < GIT_SUCCESS) {
- git__free(pack);
- return GIT_ENOMEM;
- }
+ else if (error < 0)
+ return error;
- return GIT_SUCCESS;
+ return git_vector_insert(&backend->packs, pack);
}
static int packfile_refresh_all(struct pack_backend *backend)
@@ -244,10 +239,10 @@ static int packfile_refresh_all(struct pack_backend *backend)
struct stat st;
if (backend->pack_folder == NULL)
- return GIT_SUCCESS;
+ return 0;
if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
- return git__throw(GIT_ENOTFOUND, "Failed to refresh packfiles. Backend not found");
+ return git_odb__error_notfound("failed to refresh packfiles");
if (st.st_mtime != backend->pack_folder_mtime) {
git_buf path = GIT_BUF_INIT;
@@ -257,14 +252,15 @@ static int packfile_refresh_all(struct pack_backend *backend)
error = git_path_direach(&path, packfile_load__cb, (void *)backend);
git_buf_free(&path);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to refresh packfiles");
+
+ if (error < 0)
+ return error;
git_vector_sort(&backend->packs);
backend->pack_folder_mtime = st.st_mtime;
}
- return GIT_SUCCESS;
+ return 0;
}
static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid)
@@ -272,12 +268,12 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen
int error;
size_t i;
- if ((error = packfile_refresh_all(backend)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to find pack entry");
+ if ((error = packfile_refresh_all(backend)) < 0)
+ return error;
if (backend->last_found &&
- git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == GIT_SUCCESS)
- return GIT_SUCCESS;
+ git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0)
+ return 0;
for (i = 0; i < backend->packs.length; ++i) {
struct git_pack_file *p;
@@ -286,13 +282,13 @@ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backen
if (p == backend->last_found)
continue;
- if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == GIT_SUCCESS) {
+ if (git_pack_entry_find(e, p, oid, GIT_OID_HEXSZ) == 0) {
backend->last_found = p;
- return GIT_SUCCESS;
+ return 0;
}
}
- return git__throw(GIT_ENOTFOUND, "Failed to find pack entry");
+ return git_odb__error_notfound("failed to find pack entry");
}
static int pack_entry_find_prefix(
@@ -305,16 +301,15 @@ static int pack_entry_find_prefix(
size_t i;
unsigned found = 0;
- if ((error = packfile_refresh_all(backend)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to find pack entry");
+ if ((error = packfile_refresh_all(backend)) < 0)
+ return error;
if (backend->last_found) {
error = git_pack_entry_find(e, backend->last_found, short_oid, len);
- if (error == GIT_EAMBIGUOUSOIDPREFIX) {
- return git__rethrow(error, "Failed to find pack entry. Ambiguous sha1 prefix");
- } else if (error == GIT_SUCCESS) {
+ if (error == GIT_EAMBIGUOUS)
+ return error;
+ if (!error)
found = 1;
- }
}
for (i = 0; i < backend->packs.length; ++i) {
@@ -325,24 +320,21 @@ static int pack_entry_find_prefix(
continue;
error = git_pack_entry_find(e, p, short_oid, len);
- if (error == GIT_EAMBIGUOUSOIDPREFIX) {
- return git__rethrow(error, "Failed to find pack entry. Ambiguous sha1 prefix");
- } else if (error == GIT_SUCCESS) {
- found++;
- if (found > 1)
+ if (error == GIT_EAMBIGUOUS)
+ return error;
+ if (!error) {
+ if (++found > 1)
break;
backend->last_found = p;
}
}
- if (!found) {
- return git__rethrow(GIT_ENOTFOUND, "Failed to find pack entry");
- } else if (found > 1) {
- return git__rethrow(GIT_EAMBIGUOUSOIDPREFIX, "Failed to find pack entry. Ambiguous sha1 prefix");
- } else {
- return GIT_SUCCESS;
- }
-
+ if (!found)
+ return git_odb__error_notfound("failed to find pack entry");
+ else if (found > 1)
+ return git_odb__error_ambiguous("found multiple pack entries");
+ else
+ return 0;
}
@@ -374,17 +366,15 @@ static int pack_backend__read(void **buffer_p, size_t *len_p, git_otype *type_p,
git_rawobj raw;
int error;
- if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to read pack backend");
-
- if ((error = git_packfile_unpack(&raw, e.p, &e.offset)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to read pack backend");
+ if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0 ||
+ (error = git_packfile_unpack(&raw, e.p, &e.offset)) < 0)
+ return error;
*buffer_p = raw.data;
*len_p = raw.len;
*type_p = raw.type;
- return GIT_SUCCESS;
+ return 0;
}
static int pack_backend__read_prefix(
@@ -396,40 +386,38 @@ static int pack_backend__read_prefix(
const git_oid *short_oid,
unsigned int len)
{
+ int error = 0;
+
if (len < GIT_OID_MINPREFIXLEN)
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to read pack backend. Prefix length is lower than %d.", GIT_OID_MINPREFIXLEN);
+ error = git_odb__error_ambiguous("prefix length too short");
- if (len >= GIT_OID_HEXSZ) {
+ else if (len >= GIT_OID_HEXSZ) {
/* We can fall back to regular read method */
- int error = pack_backend__read(buffer_p, len_p, type_p, backend, short_oid);
- if (error == GIT_SUCCESS)
+ error = pack_backend__read(buffer_p, len_p, type_p, backend, short_oid);
+ if (!error)
git_oid_cpy(out_oid, short_oid);
-
- return error;
} else {
struct git_pack_entry e;
git_rawobj raw;
- int error;
-
- if ((error = pack_entry_find_prefix(&e, (struct pack_backend *)backend, short_oid, len)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to read pack backend");
- if ((error = git_packfile_unpack(&raw, e.p, &e.offset)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to read pack backend");
-
- *buffer_p = raw.data;
- *len_p = raw.len;
- *type_p = raw.type;
- git_oid_cpy(out_oid, &e.sha1);
+ if ((error = pack_entry_find_prefix(
+ &e, (struct pack_backend *)backend, short_oid, len)) == 0 &&
+ (error = git_packfile_unpack(&raw, e.p, &e.offset)) == 0)
+ {
+ *buffer_p = raw.data;
+ *len_p = raw.len;
+ *type_p = raw.type;
+ git_oid_cpy(out_oid, &e.sha1);
+ }
}
- return GIT_SUCCESS;
+ return error;
}
static int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
{
struct git_pack_entry e;
- return pack_entry_find(&e, (struct pack_backend *)backend, oid) == GIT_SUCCESS;
+ return pack_entry_find(&e, (struct pack_backend *)backend, oid) == 0;
}
static void pack_backend__free(git_odb_backend *_backend)
@@ -455,19 +443,16 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
{
struct pack_backend *backend = NULL;
git_buf path = GIT_BUF_INIT;
- int error = GIT_SUCCESS;
backend = git__calloc(1, sizeof(struct pack_backend));
- if (backend == NULL)
- return GIT_ENOMEM;
-
- error = git_vector_init(&backend->packs, 8, packfile_sort__cb);
- if (error < GIT_SUCCESS)
- goto cleanup;
+ GITERR_CHECK_ALLOC(backend);
- error = git_buf_joinpath(&path, objects_dir, "pack");
- if (error < GIT_SUCCESS)
- goto cleanup;
+ if (git_vector_init(&backend->packs, 8, packfile_sort__cb) < 0 ||
+ git_buf_joinpath(&path, objects_dir, "pack") < 0)
+ {
+ git__free(backend);
+ return -1;
+ }
if (git_path_isdir(git_buf_cstr(&path)) == true) {
backend->pack_folder = git_buf_detach(&path);
@@ -482,10 +467,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
*backend_out = (git_odb_backend *)backend;
-cleanup:
- if (error < GIT_SUCCESS)
- git__free(backend);
git_buf_free(&path);
- return error;
+ return 0;
}
diff --git a/src/pack.c b/src/pack.c
index acab8734b..40b3ca77c 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -17,12 +17,12 @@
#include <zlib.h>
static int packfile_open(struct git_pack_file *p);
-static off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n);
+static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n);
int packfile_unpack_compressed(
git_rawobj *obj,
struct git_pack_file *p,
git_mwindow **w_curs,
- off_t *curpos,
+ git_off_t *curpos,
size_t size,
git_otype type);
@@ -34,12 +34,18 @@ int packfile_unpack_compressed(
* GIT_OID_MINPREFIXLEN and GIT_OID_HEXSZ.
*/
static int pack_entry_find_offset(
- off_t *offset_out,
+ git_off_t *offset_out,
git_oid *found_oid,
struct git_pack_file *p,
const git_oid *short_oid,
unsigned int len);
+static int packfile_error(const char *message)
+{
+ giterr_set(GITERR_ODB, "Invalid pack file - %s", message);
+ return -1;
+}
+
/***********************************************************
*
* PACK INDEX METHODS
@@ -58,40 +64,31 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
{
struct git_pack_idx_header *hdr;
uint32_t version, nr, i, *index;
-
void *idx_map;
size_t idx_size;
-
struct stat st;
-
- /* TODO: properly open the file without access time */
- git_file fd = p_open(path, O_RDONLY /*| O_NOATIME */);
-
int error;
-
+ /* TODO: properly open the file without access time using O_NOATIME */
+ git_file fd = git_futils_open_ro(path);
if (fd < 0)
- return git__throw(GIT_EOSERR, "Failed to check index. File missing or corrupted");
+ return fd;
- if (p_fstat(fd, &st) < GIT_SUCCESS) {
+ if (p_fstat(fd, &st) < 0 ||
+ !S_ISREG(st.st_mode) ||
+ !git__is_sizet(st.st_size) ||
+ (idx_size = (size_t)st.st_size) < 4 * 256 + 20 + 20)
+ {
p_close(fd);
- return git__throw(GIT_EOSERR, "Failed to check index. File appears to be corrupted");
- }
-
- if (!git__is_sizet(st.st_size))
- return GIT_ENOMEM;
-
- idx_size = (size_t)st.st_size;
-
- if (idx_size < 4 * 256 + 20 + 20) {
- p_close(fd);
- return git__throw(GIT_EOBJCORRUPTED, "Failed to check index. Object is corrupted");
+ giterr_set(GITERR_OS, "Failed to check pack index.");
+ return -1;
}
error = git_futils_mmap_ro(&p->index_map, fd, 0, idx_size);
+
p_close(fd);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to check index");
+ if (error < 0)
+ return error;
hdr = idx_map = p->index_map.data;
@@ -100,7 +97,7 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
if (version < 2 || version > 2) {
git_futils_mmap_free(&p->index_map);
- return git__throw(GIT_EOBJCORRUPTED, "Failed to check index. Unsupported index version");
+ return packfile_error("unsupported index version");
}
} else
@@ -116,7 +113,7 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
uint32_t n = ntohl(index[i]);
if (n < nr) {
git_futils_mmap_free(&p->index_map);
- return git__throw(GIT_EOBJCORRUPTED, "Failed to check index. Index is non-monotonic");
+ return packfile_error("index is non-monotonic");
}
nr = n;
}
@@ -131,7 +128,7 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
*/
if (idx_size != 4*256 + nr * 24 + 20 + 20) {
git_futils_mmap_free(&p->index_map);
- return git__throw(GIT_EOBJCORRUPTED, "Failed to check index. Object is corrupted");
+ return packfile_error("index is corrupted");
}
} else if (version == 2) {
/*
@@ -155,13 +152,13 @@ static int pack_index_check(const char *path, struct git_pack_file *p)
if (idx_size < min_size || idx_size > max_size) {
git_futils_mmap_free(&p->index_map);
- return git__throw(GIT_EOBJCORRUPTED, "Failed to check index. Wrong index size");
+ return packfile_error("wrong index size");
}
}
p->index_version = version;
p->num_objects = nr;
- return GIT_SUCCESS;
+ return 0;
}
static int pack_index_open(struct git_pack_file *p)
@@ -170,24 +167,26 @@ static int pack_index_open(struct git_pack_file *p)
int error;
if (p->index_map.data)
- return GIT_SUCCESS;
+ return 0;
idx_name = git__strdup(p->pack_name);
+ GITERR_CHECK_ALLOC(idx_name);
+
strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
error = pack_index_check(idx_name, p);
git__free(idx_name);
- return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to open index");
+ return error;
}
static unsigned char *pack_window_open(
struct git_pack_file *p,
git_mwindow **w_cursor,
- off_t offset,
+ git_off_t offset,
unsigned int *left)
{
- if (p->mwf.fd == -1 && packfile_open(p) < GIT_SUCCESS)
+ if (p->mwf.fd == -1 && packfile_open(p) < 0)
return NULL;
/* Since packfiles end in a hash of their content and it's
@@ -233,7 +232,7 @@ int git_packfile_unpack_header(
git_otype *type_p,
git_mwindow_file *mwf,
git_mwindow **w_curs,
- off_t *curpos)
+ git_off_t *curpos)
{
unsigned char *base;
unsigned int left;
@@ -248,35 +247,34 @@ int git_packfile_unpack_header(
// base = pack_window_open(p, w_curs, *curpos, &left);
base = git_mwindow_open(mwf, w_curs, *curpos, 20, &left);
if (base == NULL)
- return GIT_ENOMEM;
+ return -1;
used = packfile_unpack_header1(size_p, type_p, base, left);
-
if (used == 0)
- return git__throw(GIT_EOBJCORRUPTED, "Header length is zero");
+ return packfile_error("header length is zero");
*curpos += used;
- return GIT_SUCCESS;
+ return 0;
}
static int packfile_unpack_delta(
git_rawobj *obj,
struct git_pack_file *p,
git_mwindow **w_curs,
- off_t *curpos,
+ git_off_t *curpos,
size_t delta_size,
git_otype delta_type,
- off_t obj_offset)
+ git_off_t obj_offset)
{
- off_t base_offset;
+ git_off_t base_offset;
git_rawobj base, delta;
int error;
base_offset = get_delta_base(p, w_curs, curpos, delta_type, obj_offset);
if (base_offset == 0)
- return git__throw(GIT_EOBJCORRUPTED, "Delta offset is zero");
- if (base_offset < 0)
- return git__rethrow(base_offset, "Failed to get delta base");
+ return packfile_error("delta offset is zero");
+ if (base_offset < 0) /* must actually be an error code */
+ return (int)base_offset;
git_mwindow_close(w_curs);
error = git_packfile_unpack(&base, p, &base_offset);
@@ -287,35 +285,34 @@ static int packfile_unpack_delta(
*
* We'll need to do this in order to support thin packs.
*/
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Corrupted delta");
+ if (error < 0)
+ return error;
error = packfile_unpack_compressed(&delta, p, w_curs, curpos, delta_size, delta_type);
- if (error < GIT_SUCCESS) {
+ if (error < 0) {
git__free(base.data);
- return git__rethrow(error, "Corrupted delta");
+ return error;
}
obj->type = base.type;
- error = git__delta_apply(obj,
- base.data, base.len,
- delta.data, delta.len);
+ error = git__delta_apply(obj, base.data, base.len, delta.data, delta.len);
git__free(base.data);
git__free(delta.data);
/* TODO: we might want to cache this shit. eventually */
//add_delta_base_cache(p, base_offset, base, base_size, *type);
+
return error; /* error set by git__delta_apply */
}
int git_packfile_unpack(
- git_rawobj *obj,
- struct git_pack_file *p,
- off_t *obj_offset)
+ git_rawobj *obj,
+ struct git_pack_file *p,
+ git_off_t *obj_offset)
{
git_mwindow *w_curs = NULL;
- off_t curpos = *obj_offset;
+ git_off_t curpos = *obj_offset;
int error;
size_t size = 0;
@@ -330,8 +327,8 @@ int git_packfile_unpack(
obj->type = GIT_OBJ_BAD;
error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to unpack packfile");
+ if (error < 0)
+ return error;
switch (type) {
case GIT_OBJ_OFS_DELTA:
@@ -351,33 +348,30 @@ int git_packfile_unpack(
break;
default:
- error = GIT_EOBJCORRUPTED;
+ error = packfile_error("invalid packfile type in header");;
break;
}
git_mwindow_close(&w_curs);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to unpack object");
-
*obj_offset = curpos;
- return GIT_SUCCESS;
+ return error;
}
int packfile_unpack_compressed(
- git_rawobj *obj,
- struct git_pack_file *p,
- git_mwindow **w_curs,
- off_t *curpos,
- size_t size,
- git_otype type)
+ git_rawobj *obj,
+ struct git_pack_file *p,
+ git_mwindow **w_curs,
+ git_off_t *curpos,
+ size_t size,
+ git_otype type)
{
int st;
z_stream stream;
unsigned char *buffer, *in;
- buffer = git__malloc(size + 1);
- memset(buffer, 0x0, size + 1);
+ buffer = git__calloc(1, size + 1);
+ GITERR_CHECK_ALLOC(buffer);
memset(&stream, 0, sizeof(stream));
stream.next_out = buffer;
@@ -386,7 +380,8 @@ int packfile_unpack_compressed(
st = inflateInit(&stream);
if (st != Z_OK) {
git__free(buffer);
- return git__throw(GIT_EZLIB, "Error in zlib");
+ giterr_set(GITERR_ZLIB, "Failed to inflate packfile");
+ return -1;
}
do {
@@ -404,28 +399,29 @@ int packfile_unpack_compressed(
if ((st != Z_STREAM_END) || stream.total_out != size) {
git__free(buffer);
- return git__throw(GIT_EZLIB, "Error in zlib");
+ giterr_set(GITERR_ZLIB, "Failed to inflate packfile");
+ return -1;
}
obj->type = type;
obj->len = size;
obj->data = buffer;
- return GIT_SUCCESS;
+ return 0;
}
/*
* curpos is where the data starts, delta_obj_offset is the where the
* header starts
*/
-off_t get_delta_base(
- struct git_pack_file *p,
- git_mwindow **w_curs,
- off_t *curpos,
- git_otype type,
- off_t delta_obj_offset)
+git_off_t get_delta_base(
+ struct git_pack_file *p,
+ git_mwindow **w_curs,
+ git_off_t *curpos,
+ git_otype type,
+ git_off_t delta_obj_offset)
{
unsigned char *base_info = pack_window_open(p, w_curs, *curpos, NULL);
- off_t base_offset;
+ git_off_t base_offset;
git_oid unused;
/* pack_window_open() assured us we have [base_info, base_info + 20)
@@ -463,8 +459,8 @@ off_t get_delta_base(
}
}
/* The base entry _must_ be in the same pack */
- if (pack_entry_find_offset(&base_offset, &unused, p, (git_oid *)base_info, GIT_OID_HEXSZ) < GIT_SUCCESS)
- return git__rethrow(GIT_EPACKCORRUPTED, "Base entry delta is not in the same pack");
+ if (pack_entry_find_offset(&base_offset, &unused, p, (git_oid *)base_info, GIT_OID_HEXSZ) < 0)
+ return packfile_error("base entry delta is not in the same pack");
*curpos += 20;
} else
return 0;
@@ -480,9 +476,9 @@ off_t get_delta_base(
static struct git_pack_file *packfile_alloc(int extra)
{
- struct git_pack_file *p = git__malloc(sizeof(*p) + extra);
- memset(p, 0, sizeof(*p));
- p->mwf.fd = -1;
+ struct git_pack_file *p = git__calloc(1, sizeof(*p) + extra);
+ if (p != NULL)
+ p->mwf.fd = -1;
return p;
}
@@ -510,24 +506,25 @@ static int packfile_open(struct git_pack_file *p)
git_oid sha1;
unsigned char *idx_sha1;
+ assert(p->index_map.data);
+
if (!p->index_map.data && pack_index_open(p) < GIT_SUCCESS)
- return git__throw(GIT_ENOTFOUND, "Failed to open packfile. File not found");
+ return git_odb__error_notfound("failed to open packfile");
/* TODO: open with noatime */
- p->mwf.fd = p_open(p->pack_name, O_RDONLY);
- if (p->mwf.fd < 0 || p_fstat(p->mwf.fd, &st) < GIT_SUCCESS)
- return git__throw(GIT_EOSERR, "Failed to open packfile. File appears to be corrupted");
+ p->mwf.fd = git_futils_open_ro(p->pack_name);
+ if (p->mwf.fd < 0)
+ return p->mwf.fd;
- if (git_mwindow_file_register(&p->mwf) < GIT_SUCCESS) {
- p_close(p->mwf.fd);
- return git__throw(GIT_ERROR, "Failed to register packfile windows");
- }
+ if (p_fstat(p->mwf.fd, &st) < 0 ||
+ git_mwindow_file_register(&p->mwf) < 0)
+ goto cleanup;
/* If we created the struct before we had the pack we lack size. */
if (!p->mwf.size) {
if (!S_ISREG(st.st_mode))
goto cleanup;
- p->mwf.size = (off_t)st.st_size;
+ p->mwf.size = (git_off_t)st.st_size;
} else if (p->mwf.size != st.st_size)
goto cleanup;
@@ -537,44 +534,35 @@ static int packfile_open(struct git_pack_file *p)
*/
fd_flag = fcntl(p->mwf.fd, F_GETFD, 0);
if (fd_flag < 0)
- return error("cannot determine file descriptor flags");
+ goto cleanup;
fd_flag |= FD_CLOEXEC;
if (fcntl(p->pack_fd, F_SETFD, fd_flag) == -1)
- return GIT_EOSERR;
+ goto cleanup;
#endif
/* Verify we recognize this pack file format. */
- if (p_read(p->mwf.fd, &hdr, sizeof(hdr)) < GIT_SUCCESS)
- goto cleanup;
-
- if (hdr.hdr_signature != htonl(PACK_SIGNATURE))
- goto cleanup;
-
- if (!pack_version_ok(hdr.hdr_version))
+ if (p_read(p->mwf.fd, &hdr, sizeof(hdr)) < 0 ||
+ hdr.hdr_signature != htonl(PACK_SIGNATURE) ||
+ !pack_version_ok(hdr.hdr_version))
goto cleanup;
/* Verify the pack matches its index. */
- if (p->num_objects != ntohl(hdr.hdr_entries))
- goto cleanup;
-
- if (p_lseek(p->mwf.fd, p->mwf.size - GIT_OID_RAWSZ, SEEK_SET) == -1)
- goto cleanup;
-
- if (p_read(p->mwf.fd, sha1.id, GIT_OID_RAWSZ) < GIT_SUCCESS)
+ if (p->num_objects != ntohl(hdr.hdr_entries) ||
+ p_lseek(p->mwf.fd, p->mwf.size - GIT_OID_RAWSZ, SEEK_SET) == -1 ||
+ p_read(p->mwf.fd, sha1.id, GIT_OID_RAWSZ) < 0)
goto cleanup;
idx_sha1 = ((unsigned char *)p->index_map.data) + p->index_map.len - 40;
- if (git_oid_cmp(&sha1, (git_oid *)idx_sha1) != 0)
- goto cleanup;
-
- return GIT_SUCCESS;
+ if (git_oid_cmp(&sha1, (git_oid *)idx_sha1) == 0)
+ return 0;
cleanup:
+ giterr_set(GITERR_OS, "Invalid packfile '%s'", p->pack_name);
p_close(p->mwf.fd);
p->mwf.fd = -1;
- return git__throw(GIT_EPACKCORRUPTED, "Failed to open packfile. Pack is corrupted");
+ return -1;
}
int git_packfile_check(struct git_pack_file **pack_out, const char *path)
@@ -586,6 +574,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
*pack_out = NULL;
path_len = strlen(path);
p = packfile_alloc(path_len + 2);
+ GITERR_CHECK_ALLOC(p);
/*
* Make sure a corresponding .pack file exists and that
@@ -594,7 +583,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
path_len -= strlen(".idx");
if (path_len < 1) {
git__free(p);
- return git__throw(GIT_ENOTFOUND, "Failed to check packfile. Wrong path name");
+ return git_odb__error_notfound("invalid packfile path");
}
memcpy(p->pack_name, path, path_len);
@@ -604,9 +593,9 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
p->pack_keep = 1;
strcpy(p->pack_name + path_len, ".pack");
- if (p_stat(p->pack_name, &st) < GIT_SUCCESS || !S_ISREG(st.st_mode)) {
+ if (p_stat(p->pack_name, &st) < 0 || !S_ISREG(st.st_mode)) {
git__free(p);
- return git__throw(GIT_ENOTFOUND, "Failed to check packfile. File not found");
+ return git_odb__error_notfound("packfile not found");
}
/* ok, it looks sane as far as we can check without
@@ -618,11 +607,12 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
/* see if we can parse the sha1 oid in the packfile name */
if (path_len < 40 ||
- git_oid_fromstr(&p->sha1, path + path_len - GIT_OID_HEXSZ) < GIT_SUCCESS)
+ git_oid_fromstr(&p->sha1, path + path_len - GIT_OID_HEXSZ) < 0)
memset(&p->sha1, 0x0, GIT_OID_RAWSZ);
*pack_out = p;
- return GIT_SUCCESS;
+
+ return 0;
}
/***********************************************************
@@ -631,7 +621,7 @@ int git_packfile_check(struct git_pack_file **pack_out, const char *path)
*
***********************************************************/
-static off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n)
+static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n)
{
const unsigned char *index = p->index_map.data;
index += 4 * 256;
@@ -650,11 +640,11 @@ static off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n)
}
static int pack_entry_find_offset(
- off_t *offset_out,
- git_oid *found_oid,
- struct git_pack_file *p,
- const git_oid *short_oid,
- unsigned int len)
+ git_off_t *offset_out,
+ git_oid *found_oid,
+ struct git_pack_file *p,
+ const git_oid *short_oid,
+ unsigned int len)
{
const uint32_t *level1_ofs = p->index_map.data;
const unsigned char *index = p->index_map.data;
@@ -667,8 +657,8 @@ static int pack_entry_find_offset(
if (index == NULL) {
int error;
- if ((error = pack_index_open(p)) < GIT_SUCCESS)
- return git__rethrow(error, "Failed to find offset for pack entry");
+ if ((error = pack_index_open(p)) < 0)
+ return error;
assert(p->index_map.data);
@@ -726,22 +716,22 @@ static int pack_entry_find_offset(
}
}
- if (!found) {
- return git__throw(GIT_ENOTFOUND, "Failed to find offset for pack entry. Entry not found");
- } else if (found > 1) {
- return git__throw(GIT_EAMBIGUOUSOIDPREFIX, "Failed to find offset for pack entry. Ambiguous sha1 prefix within pack");
- } else {
- *offset_out = nth_packed_object_offset(p, pos);
- git_oid_fromraw(found_oid, current);
+ if (!found)
+ return git_odb__error_notfound("failed to find offset for pack entry");
+ if (found > 1)
+ return git_odb__error_ambiguous("found multiple offsets for pack entry");
+ *offset_out = nth_packed_object_offset(p, pos);
+ git_oid_fromraw(found_oid, current);
#ifdef INDEX_DEBUG_LOOKUP
+ {
unsigned char hex_sha1[GIT_OID_HEXSZ + 1];
git_oid_fmt(hex_sha1, found_oid);
hex_sha1[GIT_OID_HEXSZ] = '\0';
printf("found lo=%d %s\n", lo, hex_sha1);
-#endif
- return GIT_SUCCESS;
}
+#endif
+ return 0;
}
int git_pack_entry_find(
@@ -750,7 +740,7 @@ int git_pack_entry_find(
const git_oid *short_oid,
unsigned int len)
{
- off_t offset;
+ git_off_t offset;
git_oid found_oid;
int error;
@@ -760,22 +750,22 @@ int git_pack_entry_find(
unsigned i;
for (i = 0; i < p->num_bad_objects; i++)
if (git_oid_cmp(short_oid, &p->bad_object_sha1[i]) == 0)
- return git__throw(GIT_ERROR, "Failed to find pack entry. Bad object found");
+ return packfile_error("bad object found in packfile");
}
error = pack_entry_find_offset(&offset, &found_oid, p, short_oid, len);
- if (error < GIT_SUCCESS)
- return git__rethrow(error, "Failed to find pack entry. Couldn't find offset");
+ if (error < 0)
+ return error;
/* we found a unique entry in the index;
* make sure the packfile backing the index
* still exists on disk */
- if (p->mwf.fd == -1 && packfile_open(p) < GIT_SUCCESS)
- return git__throw(GIT_EOSERR, "Failed to find pack entry. Packfile doesn't exist on disk");
+ if (p->mwf.fd == -1 && (error = packfile_open(p)) < 0)
+ return error;
e->offset = offset;
e->p = p;
git_oid_cpy(&e->sha1, &found_oid);
- return GIT_SUCCESS;
+ return 0;
}
diff --git a/src/pack.h b/src/pack.h
index 590297847..7cf41c183 100644
--- a/src/pack.h
+++ b/src/pack.h
@@ -70,7 +70,7 @@ struct git_pack_file {
};
struct git_pack_entry {
- off_t offset;
+ git_off_t offset;
git_oid sha1;
struct git_pack_file *p;
};
@@ -80,13 +80,13 @@ int git_packfile_unpack_header(
git_otype *type_p,
git_mwindow_file *mwf,
git_mwindow **w_curs,
- off_t *curpos);
+ git_off_t *curpos);
-int git_packfile_unpack(git_rawobj *obj, struct git_pack_file *p, off_t *obj_offset);
+int git_packfile_unpack(git_rawobj *obj, struct git_pack_file *p, git_off_t *obj_offset);
-off_t get_delta_base(struct git_pack_file *p, git_mwindow **w_curs,
- off_t *curpos, git_otype type,
- off_t delta_obj_offset);
+git_off_t get_delta_base(struct git_pack_file *p, git_mwindow **w_curs,
+ git_off_t *curpos, git_otype type,
+ git_off_t delta_obj_offset);
void packfile_free(struct git_pack_file *p);
int git_packfile_check(struct git_pack_file **pack_out, const char *path);
diff --git a/src/refs.c b/src/refs.c
index e90cf5de1..b4c4b1ec1 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -842,7 +842,7 @@ static int reference_path_available(
if (!data.available) {
giterr_set(GITERR_REFERENCE,
- "The path to reference '%s' collides with an existing one");
+ "The path to reference '%s' collides with an existing one", ref);
return -1;
}
@@ -902,7 +902,7 @@ static int reference_can_write(
* the rename; the existing one would be overwritten */
if (exists) {
giterr_set(GITERR_REFERENCE,
- "A reference with that name (%s) already exists");
+ "A reference with that name (%s) already exists", refname);
return GIT_EEXISTS;
}
}
diff --git a/src/unix/map.c b/src/unix/map.c
index 67a73e43c..1e2389ec2 100644
--- a/src/unix/map.c
+++ b/src/unix/map.c
@@ -17,12 +17,8 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
int mprot = 0;
int mflag = 0;
- assert((out != NULL) && (len > 0));
-
- if ((out == NULL) || (len == 0)) {
- errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. No map or zero length");
- }
+ if (validate_map_args(out, len, prot, flags, fd, offset) < 0)
+ return -1;
out->data = NULL;
out->len = 0;
@@ -31,39 +27,28 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
mprot = PROT_WRITE;
else if (prot & GIT_PROT_READ)
mprot = PROT_READ;
- else {
- errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. Invalid protection parameters");
- }
if ((flags & GIT_MAP_TYPE) == GIT_MAP_SHARED)
mflag = MAP_SHARED;
else if ((flags & GIT_MAP_TYPE) == GIT_MAP_PRIVATE)
mflag = MAP_PRIVATE;
- if (flags & GIT_MAP_FIXED) {
- errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. FIXED not set");
+ out->data = mmap(NULL, len, mprot, mflag, fd, offset);
+ if (!out->data || out->data == MAP_FAILED) {
+ giterr_set(GITERR_OS, "Failed to mmap. Could not write data");
+ return -1;
}
- out->data = mmap(NULL, len, mprot, mflag, fd, offset);
- if (!out->data || out->data == MAP_FAILED)
- return git__throw(GIT_EOSERR, "Failed to mmap. Could not write data");
out->len = len;
- return GIT_SUCCESS;
+ return 0;
}
int p_munmap(git_map *map)
{
assert(map != NULL);
-
- if (!map)
- return git__throw(GIT_ERROR, "Failed to munmap. Map does not exist");
-
munmap(map->data, map->len);
-
- return GIT_SUCCESS;
+ return 0;
}
#endif
diff --git a/src/win32/map.c b/src/win32/map.c
index 60adf0f94..de996e0d1 100644
--- a/src/win32/map.c
+++ b/src/win32/map.c
@@ -33,12 +33,8 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
git_off_t page_start;
git_off_t page_offset;
- assert((out != NULL) && (len > 0));
-
- if ((out == NULL) || (len == 0)) {
- errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. No map or zero length");
- }
+ if (validate_map_args(out, len, prot, flags, fd, offset) < 0)
+ return -1;
out->data = NULL;
out->len = 0;
@@ -46,86 +42,75 @@ int p_mmap(git_map *out, size_t len, int prot, int flags, int fd, git_off_t offs
if (fh == INVALID_HANDLE_VALUE) {
errno = EBADF;
- return git__throw(GIT_ERROR, "Failed to mmap. Invalid handle value");
+ giterr_set(GITERR_OS, "Failed to mmap. Invalid handle value");
+ return -1;
}
if (prot & GIT_PROT_WRITE)
fmap_prot |= PAGE_READWRITE;
else if (prot & GIT_PROT_READ)
fmap_prot |= PAGE_READONLY;
- else {
- errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. Invalid protection parameters");
- }
if (prot & GIT_PROT_WRITE)
view_prot |= FILE_MAP_WRITE;
if (prot & GIT_PROT_READ)
view_prot |= FILE_MAP_READ;
- if (flags & GIT_MAP_FIXED) {
- errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. FIXED not set");
- }
-
page_start = (offset / page_size) * page_size;
page_offset = offset - page_start;
if (page_offset != 0) { /* offset must be multiple of page size */
errno = EINVAL;
- return git__throw(GIT_ERROR, "Failed to mmap. Offset must be multiple of page size");
+ giterr_set(GITERR_OS, "Failed to mmap. Offset must be multiple of page size");
+ return -1;
}
out->fmh = CreateFileMapping(fh, NULL, fmap_prot, 0, 0, NULL);
if (!out->fmh || out->fmh == INVALID_HANDLE_VALUE) {
- /* errno = ? */
+ giterr_set(GITERR_OS, "Failed to mmap. Invalid handle value");
out->fmh = NULL;
- return git__throw(GIT_ERROR, "Failed to mmap. Invalid handle value");
+ return -1;
}
assert(sizeof(git_off_t) == 8);
+
off_low = (DWORD)(page_start);
off_hi = (DWORD)(page_start >> 32);
out->data = MapViewOfFile(out->fmh, view_prot, off_hi, off_low, len);
if (!out->data) {
- /* errno = ? */
+ giterr_set(GITERR_OS, "Failed to mmap. No data written");
CloseHandle(out->fmh);
out->fmh = NULL;
- return git__throw(GIT_ERROR, "Failed to mmap. No data written");
+ return -1;
}
out->len = len;
- return GIT_SUCCESS;
+ return 0;
}
int p_munmap(git_map *map)
{
- assert(map != NULL);
+ int error = 0;
- if (!map)
- return git__throw(GIT_ERROR, "Failed to munmap. Map does not exist");
+ assert(map != NULL);
if (map->data) {
if (!UnmapViewOfFile(map->data)) {
- /* errno = ? */
- CloseHandle(map->fmh);
- map->data = NULL;
- map->fmh = NULL;
- return git__throw(GIT_ERROR, "Failed to munmap. Could not unmap view of file");
+ giterr_set(GITERR_OS, "Failed to munmap. Could not unmap view of file");
+ error = -1;
}
map->data = NULL;
}
if (map->fmh) {
if (!CloseHandle(map->fmh)) {
- /* errno = ? */
- map->fmh = NULL;
- return git__throw(GIT_ERROR, "Failed to munmap. Could not close handle");
+ giterr_set(GITERR_OS, "Failed to munmap. Could not close handle");
+ error = -1;
}
map->fmh = NULL;
}
- return GIT_SUCCESS;
+ return error;
}
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 2d7c2e3c9..a9158980b 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -1,4 +1,4 @@
-/ < 0)
+/*
* Copyright (C) 2009-2012 the libgit2 contributors
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
@@ -339,7 +339,7 @@ int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
int len;
if (count == 0 || (len = _vsnprintf(buffer, count, format, argptr)) < 0)
- return p_vscprintf(format, argptr);
+ return _vscprintf(format, argptr);
return len;
#else /* MinGW */
diff --git a/tests-clar/attr/attr_expect.h b/tests-clar/attr/attr_expect.h
index bea562457..b064eac65 100644
--- a/tests-clar/attr/attr_expect.h
+++ b/tests-clar/attr/attr_expect.h
@@ -15,7 +15,7 @@ struct attr_expected {
const char *expected_str;
};
-static inline void attr_check_expected(
+GIT_INLINE(void) attr_check_expected(
enum attr_expect_t expected,
const char *expected_str,
const char *value)