@@ -25,14 +25,14 @@ static int hash_literally(struct object_id *oid, int fd, const char *type, unsig
if (strbuf_read(&buf, fd, 4096) < 0)
ret = -1;
else
- ret = hash_object_file_literally(buf.buf, buf.len, type, oid,
- flags);
+ ret = hash_object_file_literally(buf.buf, buf.len, type,
+ strlen(type), oid, flags);
strbuf_release(&buf);
return ret;
}
-static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
- int literally)
+static void hash_fd(int fd, const char *type, size_t type_len,
+ const char *path, unsigned flags, int literally)
{
struct stat st;
struct object_id oid;
@@ -49,31 +49,32 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
maybe_flush_or_die(stdout, "hash to stdout");
}
-static void hash_object(const char *path, const char *type, const char *vpath,
- unsigned flags, int literally)
+static void hash_object(const char *path, const char *type, size_t type_len,
+ const char *vpath, unsigned flags, int literally)
{
int fd;
fd = open(path, O_RDONLY);
if (fd < 0)
die_errno("Cannot open '%s'", path);
- hash_fd(fd, type, vpath, flags, literally);
+ hash_fd(fd, type, type_len, vpath, flags, literally);
}
-static void hash_stdin_paths(const char *type, int no_filters, unsigned flags,
- int literally)
+static void hash_stdin_paths(const char *type, size_t type_len, int no_filters,
+ unsigned flags, int literally)
{
struct strbuf buf = STRBUF_INIT;
struct strbuf unquoted = STRBUF_INIT;
while (strbuf_getline(&buf, stdin) != EOF) {
+ const char *vpath;
if (buf.buf[0] == '"') {
strbuf_reset(&unquoted);
if (unquote_c_style(&unquoted, buf.buf, NULL))
die("line is badly quoted");
strbuf_swap(&buf, &unquoted);
}
- hash_object(buf.buf, type, no_filters ? NULL : buf.buf, flags,
- literally);
+ vpath = no_filters ? NULL : buf.buf;
+ hash_object(buf.buf, type, type_len, vpath , flags, literally);
}
strbuf_release(&buf);
strbuf_release(&unquoted);
@@ -87,6 +88,7 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
NULL
};
const char *type = blob_type;
+ size_t type_len;
int hashstdin = 0;
int stdin_paths = 0;
int no_filters = 0;
@@ -141,8 +143,9 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
usage_with_options(hash_object_usage, hash_object_options);
}
+ type_len = strlen(type);
if (hashstdin)
- hash_fd(0, type, vpath, flags, literally);
+ hash_fd(0, type, type_len, vpath, flags, literally);
for (i = 0 ; i < argc; i++) {
const char *arg = argv[i];
@@ -150,13 +153,13 @@ int cmd_hash_object(int argc, const char **argv, const char *prefix)
if (prefix)
arg = to_free = prefix_filename(prefix, arg);
- hash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,
+ hash_object(arg, type, type_len, no_filters ? NULL : vpath ? vpath : arg,
flags, literally);
free(to_free);
}
if (stdin_paths)
- hash_stdin_paths(type, no_filters, flags, literally);
+ hash_stdin_paths(type, type_len, no_filters, flags, literally);
return 0;
}
@@ -1715,13 +1715,15 @@ void *read_object_with_reference(struct repository *r,
static void write_object_file_prepare(const struct git_hash_algo *algo,
const void *buf, unsigned long len,
- const char *type, struct object_id *oid,
- char *hdr, int *hdrlen)
+ const char *type, size_t type_len,
+ struct object_id *oid, char *hdr,
+ int *hdrlen)
{
git_hash_ctx c;
/* Generate the header */
- *hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
+ *hdrlen = xsnprintf(hdr, *hdrlen, "%.*s %"PRIuMAX,
+ (int)type_len, type, (uintmax_t)len) + 1;
/* Sha1.. */
algo->init_fn(&c);
@@ -1786,7 +1788,8 @@ int hash_object_file(const struct git_hash_algo *algo, const void *buf,
{
char hdr[MAX_HEADER_LEN];
int hdrlen = sizeof(hdr);
- write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen);
+ write_object_file_prepare(algo, buf, len, type, strlen(type), oid, hdr,
+ &hdrlen);
return 0;
}
@@ -1940,29 +1943,30 @@ int write_object_file(const void *buf, unsigned long len, const char *type,
{
char hdr[MAX_HEADER_LEN];
int hdrlen = sizeof(hdr);
+ size_t type_len = strlen(type);
/* Normally if we have it in the pack then we do not bother writing
* it out into .git/objects/??/?{38} file.
*/
- write_object_file_prepare(the_hash_algo, buf, len, type, oid, hdr,
- &hdrlen);
+ write_object_file_prepare(the_hash_algo, buf, len, type, type_len, oid,
+ hdr, &hdrlen);
if (freshen_packed_object(oid) || freshen_loose_object(oid))
return 0;
return write_loose_object(oid, hdr, hdrlen, buf, len, 0);
}
int hash_object_file_literally(const void *buf, unsigned long len,
- const char *type, struct object_id *oid,
- unsigned flags)
+ const char *type, size_t type_len,
+ struct object_id *oid, unsigned flags)
{
char *header;
int hdrlen, status = 0;
/* type string, SP, %lu of the length plus NUL must fit this */
- hdrlen = strlen(type) + MAX_HEADER_LEN;
+ hdrlen = type_len + MAX_HEADER_LEN;
header = xmalloc(hdrlen);
- write_object_file_prepare(the_hash_algo, buf, len, type, oid, header,
- &hdrlen);
+ write_object_file_prepare(the_hash_algo, buf, len, type, type_len, oid,
+ header, &hdrlen);
if (!(flags & HASH_WRITE_OBJECT))
goto cleanup;
@@ -220,8 +220,8 @@ int write_object_file(const void *buf, unsigned long len,
const char *type, struct object_id *oid);
int hash_object_file_literally(const void *buf, unsigned long len,
- const char *type, struct object_id *oid,
- unsigned flags);
+ const char *type, size_t type_len,
+ struct object_id *oid, unsigned flags);
/*
* Add an object file to the in-memory object store, without writing it
Change the functions to do with passing the type down to hash_object_file_literally() to pass the length of the type as well as the "const char *" type name. The immediate motivation for this is to move hash-object.c over to type_from_string_gently() to emit a better error message, but it will also allow us in the future to craft an invalid object with a "\0" in the type name. We'd need to learn a --type-file=* option or similar (we can't of course, pass a string with "\0" on the command-line). Right now such an object can be manually crafted, but we can't test for it with --literally. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- builtin/hash-object.c | 31 +++++++++++++++++-------------- object-file.c | 26 +++++++++++++++----------- object-store.h | 4 ++-- 3 files changed, 34 insertions(+), 27 deletions(-)