#include "tag.h"
#include "tree.h"
-#include <sys/time.h>
-
static int dry_run, quiet, recover, has_errors;
static const char unpack_usage[] = "git-unpack-objects [-n] [-q] [-r] < pack-file";
/* We always read in 4kB chunks. */
static unsigned char buffer[4096];
-static unsigned long offset, len, consumed_bytes;
+static unsigned int offset, len;
+static off_t consumed_bytes;
static SHA_CTX ctx;
/*
die("used more bytes than were available");
len -= bytes;
offset += bytes;
+
+ /* make sure off_t is sufficiently large not to wrap */
+ if (consumed_bytes > consumed_bytes + bytes)
+ die("pack too large for current definition of off_t");
consumed_bytes += bytes;
}
struct delta_info {
unsigned char base_sha1[20];
- unsigned long base_offset;
+ unsigned nr;
+ off_t base_offset;
unsigned long size;
void *delta;
- unsigned nr;
struct delta_info *next;
};
static struct delta_info *delta_list;
static void add_delta_to_list(unsigned nr, unsigned const char *base_sha1,
- unsigned long base_offset,
+ off_t base_offset,
void *delta, unsigned long size)
{
struct delta_info *info = xmalloc(sizeof(*info));
}
struct obj_info {
- unsigned long offset;
+ off_t offset;
unsigned char sha1[20];
};
static struct obj_info *obj_list;
-static void added_object(unsigned nr, const char *type, void *data,
- unsigned long size);
+static void added_object(unsigned nr, enum object_type type,
+ void *data, unsigned long size);
-static void write_object(unsigned nr, void *buf, unsigned long size,
- const char *type)
+static void write_object(unsigned nr, enum object_type type,
+ void *buf, unsigned long size)
{
- if (write_sha1_file(buf, size, type, obj_list[nr].sha1) < 0)
+ if (write_sha1_file(buf, size, typename(type), obj_list[nr].sha1) < 0)
die("failed to write object");
added_object(nr, type, buf, size);
}
-static void resolve_delta(unsigned nr, const char *type,
+static void resolve_delta(unsigned nr, enum object_type type,
void *base, unsigned long base_size,
void *delta, unsigned long delta_size)
{
if (!result)
die("failed to apply delta");
free(delta);
- write_object(nr, result, result_size, type);
+ write_object(nr, type, result, result_size);
free(result);
}
-static void added_object(unsigned nr, const char *type, void *data,
- unsigned long size)
+static void added_object(unsigned nr, enum object_type type,
+ void *data, unsigned long size)
{
struct delta_info **p = &delta_list;
struct delta_info *info;
}
}
-static void unpack_non_delta_entry(enum object_type kind, unsigned long size,
+static void unpack_non_delta_entry(enum object_type type, unsigned long size,
unsigned nr)
{
void *buf = get_data(size);
- const char *type;
-
- switch (kind) {
- case OBJ_COMMIT: type = commit_type; break;
- case OBJ_TREE: type = tree_type; break;
- case OBJ_BLOB: type = blob_type; break;
- case OBJ_TAG: type = tag_type; break;
- default: die("bad type %d", kind);
- }
+
if (!dry_run && buf)
- write_object(nr, buf, size, type);
+ write_object(nr, type, buf, size);
free(buf);
}
-static void unpack_delta_entry(enum object_type kind, unsigned long delta_size,
+static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
unsigned nr)
{
void *delta_data, *base;
unsigned long base_size;
- char type[20];
unsigned char base_sha1[20];
- if (kind == OBJ_REF_DELTA) {
+ if (type == OBJ_REF_DELTA) {
hashcpy(base_sha1, fill(20));
use(20);
delta_data = get_data(delta_size);
} else {
unsigned base_found = 0;
unsigned char *pack, c;
- unsigned long base_offset;
+ off_t base_offset;
unsigned lo, mid, hi;
pack = fill(1);
base_offset = c & 127;
while (c & 128) {
base_offset += 1;
- if (!base_offset || base_offset & ~(~0UL >> 7))
+ if (!base_offset || MSB(base_offset, 7))
die("offset value overflow for delta base object");
pack = fill(1);
c = *pack;
}
}
- base = read_sha1_file(base_sha1, type, &base_size);
+ base = read_sha1_file(base_sha1, &type, &base_size);
if (!base) {
error("failed to read delta-pack base object %s",
sha1_to_hex(base_sha1));
recover = 1;
continue;
}
- if (!strncmp(arg, "--pack_header=", 14)) {
+ if (!prefixcmp(arg, "--pack_header=")) {
struct pack_header *hdr;
char *c;