Unverified Commit d9863fc1 by Edward Thomson Committed by GitHub

Merge pull request #6192 from libgit2/ethomson/sha256_preparation

SHA256: early preparation
parents 4efd6563 70d9bfa4
......@@ -17,7 +17,6 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv)
git_indexer *idx;
git_indexer_progress stats = {0, 0};
int error;
char hash[GIT_OID_HEXSZ + 1] = {0};
int fd;
ssize_t read_bytes;
char buf[512];
......@@ -61,8 +60,7 @@ int lg2_index_pack(git_repository *repo, int argc, char **argv)
printf("\rIndexing %u of %u\n", stats.indexed_objects, stats.total_objects);
git_oid_fmt(hash, git_indexer_hash(idx));
puts(hash);
puts(git_indexer_name(idx));
cleanup:
close(fd);
......
......@@ -101,13 +101,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
if (git_indexer_commit(indexer, &stats) < 0)
goto cleanup;
if (git_str_printf(&path, "pack-%s.idx", git_oid_tostr_s(git_indexer_hash(indexer))) < 0)
if (git_str_printf(&path, "pack-%s.idx", git_indexer_name(indexer)) < 0)
goto cleanup;
p_unlink(git_str_cstr(&path));
git_str_clear(&path);
if (git_str_printf(&path, "pack-%s.pack", git_oid_tostr_s(git_indexer_hash(indexer))) < 0)
if (git_str_printf(&path, "pack-%s.pack", git_indexer_name(indexer)) < 0)
goto cleanup;
p_unlink(git_str_cstr(&path));
......
......@@ -296,6 +296,7 @@ GIT_EXTERN(int) git_index_write(git_index *index);
*/
GIT_EXTERN(const char *) git_index_path(const git_index *index);
#ifndef GIT_DEPRECATE_HARD
/**
* Get the checksum of the index
*
......@@ -303,10 +304,12 @@ GIT_EXTERN(const char *) git_index_path(const git_index *index);
* last 20 bytes which are the checksum itself). In cases where the
* index does not exist on-disk, it will be zeroed out.
*
* @deprecated this function is deprecated with no replacement
* @param index an existing index object
* @return a pointer to the checksum of the index
*/
GIT_EXTERN(const git_oid *) git_index_checksum(git_index *index);
#endif
/**
* Read a tree into the index file with stats
......
......@@ -129,16 +129,30 @@ GIT_EXTERN(int) git_indexer_append(git_indexer *idx, const void *data, size_t si
*/
GIT_EXTERN(int) git_indexer_commit(git_indexer *idx, git_indexer_progress *stats);
#ifndef GIT_DEPRECATE_HARD
/**
* Get the packfile's hash
*
* A packfile's name is derived from the sorted hashing of all object
* names. This is only correct after the index has been finalized.
*
* @deprecated use git_indexer_name
* @param idx the indexer instance
* @return the packfile's hash
*/
GIT_EXTERN(const git_oid *) git_indexer_hash(const git_indexer *idx);
#endif
/**
* Get the unique name for the resulting packfile.
*
* The packfile's name is derived from the packfile's content.
* This is only correct after the index has been finalized.
*
* @param idx the indexer instance
* @return a NUL terminated string for the packfile name
*/
GIT_EXTERN(const char *) git_indexer_name(const git_indexer *idx);
/**
* Free the indexer and its resources
......
......@@ -170,16 +170,30 @@ GIT_EXTERN(int) git_packbuilder_write(
git_indexer_progress_cb progress_cb,
void *progress_cb_payload);
#ifndef GIT_DEPRECATE_HARD
/**
* Get the packfile's hash
*
* A packfile's name is derived from the sorted hashing of all object
* names. This is only correct after the packfile has been written.
*
* @param pb The packbuilder object
* Get the packfile's hash
*
* A packfile's name is derived from the sorted hashing of all object
* names. This is only correct after the packfile has been written.
*
* @deprecated use git_packbuilder_name
* @param pb The packbuilder object
* @return 0 or an error code
*/
*/
GIT_EXTERN(const git_oid *) git_packbuilder_hash(git_packbuilder *pb);
#endif
/**
* Get the unique name for the resulting packfile.
*
* The packfile's name is derived from the packfile's content.
* This is only correct after the packfile has been written.
*
* @param pb the packbuilder instance
* @return a NUL terminated string for the packfile name
*/
GIT_EXTERN(const char *) git_packbuilder_name(git_packbuilder *pb);
/**
* Callback used to iterate over packed objects
......
......@@ -123,7 +123,10 @@ int git_branch_create(
const git_commit *commit,
int force)
{
return create_branch(ref_out, repository, branch_name, commit, git_oid_tostr_s(git_commit_id(commit)), force);
char commit_id[GIT_OID_HEXSZ + 1];
git_oid_tostr(commit_id, GIT_OID_HEXSZ + 1, git_commit_id(commit));
return create_branch(ref_out, repository, branch_name, commit, commit_id, force);
}
int git_branch_create_from_annotated(
......
......@@ -201,7 +201,8 @@ int git_commit_graph_file_parse(
struct git_commit_graph_chunk *last_chunk;
uint32_t i;
off64_t last_chunk_offset, chunk_offset, trailer_offset;
git_oid cgraph_checksum = {{0}};
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size;
int error;
struct git_commit_graph_chunk chunk_oid_fanout = {0}, chunk_oid_lookup = {0},
chunk_commit_data = {0}, chunk_extra_edge_list = {0},
......@@ -227,13 +228,15 @@ int git_commit_graph_file_parse(
*/
last_chunk_offset = sizeof(struct git_commit_graph_header) + (1 + hdr->chunks) * 12;
trailer_offset = size - GIT_OID_RAWSZ;
checksum_size = GIT_HASH_SHA1_SIZE;
if (trailer_offset < last_chunk_offset)
return commit_graph_error("wrong commit-graph size");
git_oid_cpy(&file->checksum, (git_oid *)(data + trailer_offset));
memcpy(file->checksum, (data + trailer_offset), checksum_size);
if (git_hash_buf(cgraph_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0)
if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0)
return commit_graph_error("could not calculate signature");
if (!git_oid_equal(&cgraph_checksum, &file->checksum))
if (memcmp(checksum, file->checksum, checksum_size) != 0)
return commit_graph_error("index signature mismatch");
chunk_hdr = data + sizeof(struct git_commit_graph_header);
......@@ -476,7 +479,8 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons
git_file fd = -1;
struct stat st;
ssize_t bytes_read;
git_oid cgraph_checksum = {{0}};
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size = GIT_HASH_SHA1_SIZE;
/* TODO: properly open the file without access time using O_NOATIME */
fd = git_futils_open_ro(path);
......@@ -494,12 +498,12 @@ bool git_commit_graph_file_needs_refresh(const git_commit_graph_file *file, cons
return true;
}
bytes_read = p_pread(fd, cgraph_checksum.id, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ);
bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - checksum_size);
p_close(fd);
if (bytes_read != GIT_OID_RAWSZ)
if (bytes_read != (ssize_t)checksum_size)
return true;
return !git_oid_equal(&cgraph_checksum, &file->checksum);
return (memcmp(checksum, file->checksum, checksum_size) != 0);
}
int git_commit_graph_entry_find(
......@@ -974,7 +978,8 @@ static int commit_graph_write(
off64_t offset;
git_str oid_lookup = GIT_STR_INIT, commit_data = GIT_STR_INIT,
extra_edge_list = GIT_STR_INIT;
git_oid cgraph_checksum = {{0}};
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size;
git_hash_ctx ctx;
struct commit_graph_write_hash_context hash_cb_data = {0};
......@@ -987,6 +992,7 @@ static int commit_graph_write(
hash_cb_data.cb_data = cb_data;
hash_cb_data.ctx = &ctx;
checksum_size = GIT_HASH_SHA1_SIZE;
error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1);
if (error < 0)
return error;
......@@ -1133,10 +1139,10 @@ static int commit_graph_write(
goto cleanup;
/* Finalize the checksum and write the trailer. */
error = git_hash_final(cgraph_checksum.id, &ctx);
error = git_hash_final(checksum, &ctx);
if (error < 0)
goto cleanup;
error = write_cb((const char *)&cgraph_checksum, sizeof(cgraph_checksum), cb_data);
error = write_cb((char *)checksum, checksum_size, cb_data);
if (error < 0)
goto cleanup;
......
......@@ -15,6 +15,8 @@
#include "map.h"
#include "vector.h"
#include "oid.h"
#include "hash.h"
/**
* A commit-graph file.
......@@ -55,7 +57,7 @@ typedef struct git_commit_graph_file {
size_t num_extra_edge_list;
/* The trailer of the file. Contains the SHA1-checksum of the whole file. */
git_oid checksum;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
} git_commit_graph_file;
/**
......
......@@ -19,13 +19,14 @@
#include "regexp.h"
#include "sysdir.h"
#include "wildmatch.h"
#include "hash.h"
/* Max depth for [include] directives */
#define MAX_INCLUDE_DEPTH 10
typedef struct config_file {
git_futils_filestamp stamp;
git_oid checksum;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
char *path;
git_array_t(struct config_file) includes;
} config_file;
......@@ -132,7 +133,7 @@ static int config_file_is_modified(int *modified, config_file *file)
{
config_file *include;
git_str buf = GIT_STR_INIT;
git_oid hash;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
uint32_t i;
int error = 0;
......@@ -144,10 +145,10 @@ static int config_file_is_modified(int *modified, config_file *file)
if ((error = git_futils_readbuffer(&buf, file->path)) < 0)
goto out;
if ((error = git_hash_buf(hash.id, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0)
if ((error = git_hash_buf(checksum, buf.ptr, buf.size, GIT_HASH_ALGORITHM_SHA1)) < 0)
goto out;
if (!git_oid_equal(&hash, &file->checksum)) {
if (memcmp(checksum, file->checksum, GIT_HASH_SHA1_SIZE) != 0) {
*modified = 1;
goto out;
}
......@@ -880,7 +881,7 @@ static int config_file_read(
goto out;
git_futils_filestamp_set_from_stat(&file->stamp, &st);
if ((error = git_hash_buf(file->checksum.id, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0)
if ((error = git_hash_buf(file->checksum, contents.ptr, contents.size, GIT_HASH_ALGORITHM_SHA1)) < 0)
goto out;
if ((error = config_file_read_buffer(entries, repo, file, level, depth,
......
......@@ -124,3 +124,19 @@ done:
return error;
}
int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len)
{
static char hex[] = "0123456789abcdef";
char *str = out;
size_t i;
for (i = 0; i < hash_len; i++) {
*str++ = hex[hash[i] >> 4];
*str++ = hex[hash[i] & 0x0f];
}
*str++ = '\0';
return 0;
}
......@@ -41,4 +41,6 @@ int git_hash_final(unsigned char *out, git_hash_ctx *c);
int git_hash_buf(unsigned char *out, const void *data, size_t len, git_hash_algorithm_t algorithm);
int git_hash_vec(unsigned char *out, git_str_vec *vec, size_t n, git_hash_algorithm_t algorithm);
int git_hash_fmt(char *out, unsigned char *hash, size_t hash_len);
#endif
......@@ -34,7 +34,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr
#define minimal_entry_size (offsetof(struct entry_short, path))
static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ;
static const size_t INDEX_HEADER_SIZE = 12;
static const unsigned int INDEX_VERSION_NUMBER_DEFAULT = 2;
......@@ -121,7 +120,7 @@ static int read_header(struct index_header *dest, const void *buffer);
static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
static bool is_index_extended(git_index *index);
static int write_index(git_oid *checksum, git_index *index, git_filebuf *file);
static int write_index(unsigned char checksum[GIT_HASH_SHA1_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file);
static void index_entry_free(git_index_entry *entry);
static void index_entry_reuc_free(git_index_reuc_entry *reuc);
......@@ -607,10 +606,12 @@ int git_index_caps(const git_index *index)
(index->no_symlinks ? GIT_INDEX_CAPABILITY_NO_SYMLINKS : 0));
}
#ifndef GIT_DEPRECATE_HARD
const git_oid *git_index_checksum(git_index *index)
{
return &index->checksum;
return (git_oid *)index->checksum;
}
#endif
/**
* Returns 1 for changed, 0 for not changed and <0 for errors
......@@ -619,24 +620,25 @@ static int compare_checksum(git_index *index)
{
int fd;
ssize_t bytes_read;
git_oid checksum = {{ 0 }};
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size = GIT_HASH_SHA1_SIZE;
if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0)
return fd;
if (p_lseek(fd, -20, SEEK_END) < 0) {
if (p_lseek(fd, (0 - (ssize_t)checksum_size), SEEK_END) < 0) {
p_close(fd);
git_error_set(GIT_ERROR_OS, "failed to seek to end of file");
return -1;
}
bytes_read = p_read(fd, &checksum, GIT_OID_RAWSZ);
bytes_read = p_read(fd, checksum, checksum_size);
p_close(fd);
if (bytes_read < 0)
if (bytes_read < (ssize_t)checksum_size)
return -1;
return !!git_oid_cmp(&checksum, &index->checksum);
return !!memcmp(checksum, index->checksum, checksum_size);
}
int git_index_read(git_index *index, int force)
......@@ -703,16 +705,6 @@ int git_index_read_safely(git_index *index)
return git_index_read(index, false);
}
int git_index__changed_relative_to(
git_index *index, const git_oid *checksum)
{
/* attempt to update index (ignoring errors) */
if (git_index_read(index, false) < 0)
git_error_clear();
return !!git_oid_cmp(&index->checksum, checksum);
}
static bool is_racy_entry(git_index *index, const git_index_entry *entry)
{
/* Git special-cases submodules in the check */
......@@ -2470,8 +2462,9 @@ static int read_entry(
git_index_entry entry = {{0}};
bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP;
char *tmp_path = NULL;
size_t checksum_size = GIT_HASH_SHA1_SIZE;
if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
if (checksum_size + minimal_entry_size > buffer_size)
return -1;
/* buffer is not guaranteed to be aligned */
......@@ -2552,7 +2545,7 @@ static int read_entry(
if (entry_size == 0)
return -1;
if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
if (checksum_size + entry_size > buffer_size)
return -1;
if (index_entry_dup(out, index, &entry) < 0) {
......@@ -2586,6 +2579,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer
{
struct index_extension dest;
size_t total_size;
size_t checksum_size = GIT_HASH_SHA1_SIZE;
/* buffer is not guaranteed to be aligned */
memcpy(&dest, buffer, sizeof(struct index_extension));
......@@ -2595,7 +2589,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer
if (dest.extension_size > total_size ||
buffer_size < total_size ||
buffer_size - total_size < INDEX_FOOTER_SIZE) {
buffer_size - total_size < checksum_size) {
index_error_invalid("extension is truncated");
return -1;
}
......@@ -2632,7 +2626,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
int error = 0;
unsigned int i;
struct index_header header = { 0 };
git_oid checksum_calculated, checksum_expected;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size = GIT_HASH_SHA1_SIZE;
const char *last = NULL;
const char *empty = "";
......@@ -2644,12 +2639,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
buffer_size -= _increase;\
}
if (buffer_size < INDEX_HEADER_SIZE + INDEX_FOOTER_SIZE)
if (buffer_size < INDEX_HEADER_SIZE + checksum_size)
return index_error_invalid("insufficient buffer space");
/* Precalculate the SHA1 of the files's contents -- we'll match it to
* the provided SHA1 in the footer */
git_hash_buf(checksum_calculated.id, buffer, buffer_size - INDEX_FOOTER_SIZE, GIT_HASH_ALGORITHM_SHA1);
git_hash_buf(checksum, buffer, buffer_size - checksum_size, GIT_HASH_ALGORITHM_SHA1);
/* Parse header */
if ((error = read_header(&header, buffer)) < 0)
......@@ -2667,7 +2662,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
return error;
/* Parse all the entries */
for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
for (i = 0; i < header.entry_count && buffer_size > checksum_size; ++i) {
git_index_entry *entry = NULL;
size_t entry_size;
......@@ -2699,7 +2694,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
}
/* There's still space for some extensions! */
while (buffer_size > INDEX_FOOTER_SIZE) {
while (buffer_size > checksum_size) {
size_t extension_size;
if ((error = read_extension(&extension_size, index, buffer, buffer_size)) < 0) {
......@@ -2709,22 +2704,20 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
seek_forward(extension_size);
}
if (buffer_size != INDEX_FOOTER_SIZE) {
if (buffer_size != checksum_size) {
error = index_error_invalid(
"buffer size does not match index footer size");
goto done;
}
/* 160-bit SHA-1 over the content of the index file before this checksum. */
git_oid_fromraw(&checksum_expected, (const unsigned char *)buffer);
if (git_oid__cmp(&checksum_calculated, &checksum_expected) != 0) {
if (memcmp(checksum, buffer, checksum_size) != 0) {
error = index_error_invalid(
"calculated checksum does not match expected");
goto done;
}
git_oid_cpy(&index->checksum, &checksum_calculated);
memcpy(index->checksum, checksum, checksum_size);
#undef seek_forward
......@@ -3040,9 +3033,12 @@ static void clear_uptodate(git_index *index)
entry->flags_extended &= ~GIT_INDEX_ENTRY_UPTODATE;
}
static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
static int write_index(
unsigned char checksum[GIT_HASH_SHA1_SIZE],
size_t *checksum_size,
git_index *index,
git_filebuf *file)
{
git_oid hash_final;
struct index_header header;
bool is_extended;
uint32_t index_version_number;
......@@ -3050,6 +3046,8 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
GIT_ASSERT_ARG(index);
GIT_ASSERT_ARG(file);
*checksum_size = GIT_HASH_SHA1_SIZE;
if (index->version <= INDEX_VERSION_NUMBER_EXT) {
is_extended = is_index_extended(index);
index_version_number = is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER_LB;
......@@ -3080,11 +3078,10 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
return -1;
/* get out the hash for all the contents we've appended to the file */
git_filebuf_hash(hash_final.id, file);
git_oid_cpy(checksum, &hash_final);
git_filebuf_hash(checksum, file);
/* write it at the end of the file */
if (git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ) < 0)
if (git_filebuf_write(file, checksum, *checksum_size) < 0)
return -1;
/* file entries are no longer up to date */
......@@ -3714,8 +3711,9 @@ int git_indexwriter_init_for_operation(
int git_indexwriter_commit(git_indexwriter *writer)
{
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size;
int error;
git_oid checksum = {{ 0 }};
if (!writer->should_write)
return 0;
......@@ -3723,7 +3721,7 @@ int git_indexwriter_commit(git_indexwriter *writer)
git_vector_sort(&writer->index->entries);
git_vector_sort(&writer->index->reuc);
if ((error = write_index(&checksum, writer->index, &writer->file)) < 0) {
if ((error = write_index(checksum, &checksum_size, writer->index, &writer->file)) < 0) {
git_indexwriter_cleanup(writer);
return error;
}
......@@ -3739,7 +3737,7 @@ int git_indexwriter_commit(git_indexwriter *writer)
writer->index->dirty = 0;
writer->index->on_disk = 1;
git_oid_cpy(&writer->index->checksum, &checksum);
memcpy(writer->index->checksum, checksum, checksum_size);
git_index_free(writer->index);
writer->index = NULL;
......
......@@ -27,7 +27,7 @@ struct git_index {
char *index_file_path;
git_futils_filestamp stamp;
git_oid checksum; /* checksum at the end of the file */
unsigned char checksum[GIT_HASH_SHA1_SIZE];
git_vector entries;
git_idxmap *entries_map;
......@@ -133,10 +133,13 @@ extern unsigned int git_index__create_mode(unsigned int mode);
GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index)
{
return &index->stamp;
return &index->stamp;
}
extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum);
GIT_INLINE(unsigned char *) git_index__checksum(git_index *index)
{
return index->checksum;
}
/* Copy the current entries vector *and* increment the index refcount.
* Call `git_index__release_snapshot` when done.
......
......@@ -55,7 +55,8 @@ struct git_indexer {
git_vector deltas;
unsigned int fanout[256];
git_hash_ctx hash_ctx;
git_oid hash;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
char name[(GIT_HASH_SHA1_SIZE * 2) + 1];
git_indexer_progress_cb progress_cb;
void *progress_payload;
char objbuf[8*1024];
......@@ -76,9 +77,16 @@ struct delta_info {
off64_t delta_off;
};
#ifndef GIT_DEPRECATE_HARD
const git_oid *git_indexer_hash(const git_indexer *idx)
{
return &idx->hash;
return (git_oid *)idx->checksum;
}
#endif
const char *git_indexer_name(const git_indexer *idx)
{
return idx->name;
}
static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack)
......@@ -897,8 +905,7 @@ static int index_path(git_str *path, git_indexer *idx, const char *suffix)
git_str_truncate(path, slash);
git_str_puts(path, prefix);
git_oid_fmt(path->ptr + git_str_len(path), &idx->hash);
path->size += GIT_OID_HEXSZ;
git_str_puts(path, idx->name);
git_str_puts(path, suffix);
return git_str_oom(path) ? -1 : 0;
......@@ -919,12 +926,13 @@ static int inject_object(git_indexer *idx, git_oid *id)
git_odb_object *obj = NULL;
struct entry *entry = NULL;
struct git_pack_entry *pentry = NULL;
git_oid foo = {{0}};
unsigned char empty_checksum[GIT_HASH_SHA1_SIZE] = {0};
unsigned char hdr[64];
git_str buf = GIT_STR_INIT;
off64_t entry_start;
const void *data;
size_t len, hdr_len;
size_t checksum_size = GIT_HASH_SHA1_SIZE;
int error;
if ((error = seek_back_trailer(idx)) < 0)
......@@ -966,7 +974,7 @@ static int inject_object(git_indexer *idx, git_oid *id)
/* Write a fake trailer so the pack functions play ball */
if ((error = append_to_pack(idx, &foo, GIT_OID_RAWSZ)) < 0)
if ((error = append_to_pack(idx, empty_checksum, checksum_size)) < 0)
goto cleanup;
idx->pack->mwf.size += GIT_OID_RAWSZ;
......@@ -1160,9 +1168,11 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
struct git_pack_idx_header hdr;
git_str filename = GIT_STR_INIT;
struct entry *entry;
git_oid trailer_hash, file_hash;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
git_filebuf index_file = {0};
void *packfile_trailer;
size_t checksum_size = GIT_HASH_SHA1_SIZE;
bool mismatch;
if (!idx->parsed_header) {
git_error_set(GIT_ERROR_INDEXER, "incomplete pack header");
......@@ -1170,27 +1180,27 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
}
/* Test for this before resolve_deltas(), as it plays with idx->off */
if (idx->off + 20 < idx->pack->mwf.size) {
if (idx->off + (ssize_t)checksum_size < idx->pack->mwf.size) {
git_error_set(GIT_ERROR_INDEXER, "unexpected data at the end of the pack");
return -1;
}
if (idx->off + 20 > idx->pack->mwf.size) {
if (idx->off + (ssize_t)checksum_size > idx->pack->mwf.size) {
git_error_set(GIT_ERROR_INDEXER, "missing trailer at the end of the pack");
return -1;
}
packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left);
packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - checksum_size, checksum_size, &left);
if (packfile_trailer == NULL) {
git_mwindow_close(&w);
goto on_error;
}
/* Compare the packfile trailer as it was sent to us and what we calculated */
git_oid_fromraw(&file_hash, packfile_trailer);
git_hash_final(checksum, &idx->trailer);
mismatch = !!memcmp(checksum, packfile_trailer, checksum_size);
git_mwindow_close(&w);
git_hash_final(trailer_hash.id, &idx->trailer);
if (git_oid_cmp(&file_hash, &trailer_hash)) {
if (mismatch) {
git_error_set(GIT_ERROR_INDEXER, "packfile trailer mismatch");
return -1;
}
......@@ -1210,8 +1220,8 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
if (update_header_and_rehash(idx, stats) < 0)
return -1;
git_hash_final(trailer_hash.id, &idx->trailer);
write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ);
git_hash_final(checksum, &idx->trailer);
write_at(idx, checksum, idx->pack->mwf.size - checksum_size, checksum_size);
}
/*
......@@ -1230,7 +1240,9 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
/* Use the trailer hash as the pack file name to ensure
* files with different contents have different names */
git_oid_cpy(&idx->hash, &trailer_hash);
memcpy(idx->checksum, checksum, checksum_size);
if (git_hash_fmt(idx->name, checksum, checksum_size) < 0)
return -1;
git_str_sets(&filename, idx->pack->pack_name);
git_str_shorten(&filename, strlen("pack"));
......@@ -1291,14 +1303,14 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
}
/* Write out the packfile trailer to the index */
if (git_filebuf_write(&index_file, &trailer_hash, GIT_OID_RAWSZ) < 0)
if (git_filebuf_write(&index_file, checksum, checksum_size) < 0)
goto on_error;
/* Write out the hash of the idx */
if (git_filebuf_hash(trailer_hash.id, &index_file) < 0)
if (git_filebuf_hash(checksum, &index_file) < 0)
goto on_error;
git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid));
git_filebuf_write(&index_file, checksum, checksum_size);
/* Figure out what the final name should be */
if (index_path(&filename, idx, ".idx") < 0)
......
......@@ -178,7 +178,8 @@ int git_midx_parse(
struct git_midx_chunk *last_chunk;
uint32_t i;
off64_t last_chunk_offset, chunk_offset, trailer_offset;
git_oid idx_checksum = {{0}};
size_t checksum_size;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
int error;
struct git_midx_chunk chunk_packfile_names = {0},
chunk_oid_fanout = {0},
......@@ -208,14 +209,17 @@ int git_midx_parse(
last_chunk_offset =
sizeof(struct git_midx_header) +
(1 + hdr->chunks) * 12;
trailer_offset = size - GIT_OID_RAWSZ;
checksum_size = GIT_HASH_SHA1_SIZE;
trailer_offset = size - checksum_size;
if (trailer_offset < last_chunk_offset)
return midx_error("wrong index size");
git_oid_cpy(&idx->checksum, (git_oid *)(data + trailer_offset));
memcpy(idx->checksum, data + trailer_offset, checksum_size);
if (git_hash_buf(idx_checksum.id, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0)
if (git_hash_buf(checksum, data, (size_t)trailer_offset, GIT_HASH_ALGORITHM_SHA1) < 0)
return midx_error("could not calculate signature");
if (!git_oid_equal(&idx_checksum, &idx->checksum))
if (memcmp(checksum, idx->checksum, checksum_size) != 0)
return midx_error("index signature mismatch");
chunk_hdr = data + sizeof(struct git_midx_header);
......@@ -341,7 +345,8 @@ bool git_midx_needs_refresh(
git_file fd = -1;
struct stat st;
ssize_t bytes_read;
git_oid idx_checksum = {{0}};
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size;
/* TODO: properly open the file without access time using O_NOATIME */
fd = git_futils_open_ro(path);
......@@ -360,13 +365,14 @@ bool git_midx_needs_refresh(
return true;
}
bytes_read = p_pread(fd, &idx_checksum, GIT_OID_RAWSZ, st.st_size - GIT_OID_RAWSZ);
checksum_size = GIT_HASH_SHA1_SIZE;
bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_RAWSZ);
p_close(fd);
if (bytes_read != GIT_OID_RAWSZ)
if (bytes_read != (ssize_t)checksum_size)
return true;
return !git_oid_equal(&idx_checksum, &idx->checksum);
return (memcmp(checksum, idx->checksum, checksum_size) != 0);
}
int git_midx_entry_find(
......@@ -653,7 +659,8 @@ static int midx_write(
oid_lookup = GIT_STR_INIT,
object_offsets = GIT_STR_INIT,
object_large_offsets = GIT_STR_INIT;
git_oid idx_checksum = {{0}};
unsigned char checksum[GIT_HASH_SHA1_SIZE];
size_t checksum_size;
git_midx_entry *entry;
object_entry_array_t object_entries_array = GIT_ARRAY_INIT;
git_vector object_entries = GIT_VECTOR_INIT;
......@@ -669,6 +676,7 @@ static int midx_write(
hash_cb_data.cb_data = cb_data;
hash_cb_data.ctx = &ctx;
checksum_size = GIT_HASH_SHA1_SIZE;
error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1);
if (error < 0)
return error;
......@@ -820,10 +828,10 @@ static int midx_write(
goto cleanup;
/* Finalize the checksum and write the trailer. */
error = git_hash_final(idx_checksum.id, &ctx);
error = git_hash_final(checksum, &ctx);
if (error < 0)
goto cleanup;
error = write_cb((const char *)&idx_checksum, sizeof(idx_checksum), cb_data);
error = write_cb((char *)checksum, checksum_size, cb_data);
if (error < 0)
goto cleanup;
......
......@@ -51,7 +51,7 @@ typedef struct git_midx_file {
size_t num_object_large_offsets;
/* The trailer of the file. Contains the SHA1-checksum of the whole file. */
git_oid checksum;
unsigned char checksum[GIT_HASH_SHA1_SIZE];
/* something like ".git/objects/pack/multi-pack-index". */
git_str filename;
......
......@@ -1422,7 +1422,12 @@ int git_packbuilder_write(
if ((error = git_indexer_commit(indexer, &stats)) < 0)
goto cleanup;
#ifndef GIT_DEPRECATE_HARD
git_oid_cpy(&pb->pack_oid, git_indexer_hash(indexer));
#endif
pb->pack_name = git__strdup(git_indexer_name(indexer));
GIT_ERROR_CHECK_ALLOC(pb->pack_name);
cleanup:
git_indexer_free(indexer);
......@@ -1432,10 +1437,17 @@ cleanup:
#undef PREPARE_PACK
#ifndef GIT_DEPRECATE_HARD
const git_oid *git_packbuilder_hash(git_packbuilder *pb)
{
return &pb->pack_oid;
}
#endif
const char *git_packbuilder_name(git_packbuilder *pb)
{
return pb->pack_name;
}
static int cb_tree_walk(
......@@ -1803,5 +1815,7 @@ void git_packbuilder_free(git_packbuilder *pb)
git_hash_ctx_cleanup(&pb->ctx);
git_zstream_free(&pb->zstream);
git__free(pb->pack_name);
git__free(pb);
}
......@@ -73,7 +73,10 @@ struct git_packbuilder {
git_oidmap *walk_objects;
git_pool object_pool;
#ifndef GIT_DEPRECATE_HARD
git_oid pack_oid; /* hash of written pack */
#endif
char *pack_name; /* name of written pack */
/* synchronization objects */
git_mutex cache_mutex;
......
......@@ -188,7 +188,10 @@ int git_reset(
git_reset_t reset_type,
const git_checkout_options *checkout_opts)
{
return reset(repo, target, git_oid_tostr_s(git_object_id(target)), reset_type, checkout_opts);
char to[GIT_OID_HEXSZ + 1];
git_oid_tostr(to, GIT_OID_HEXSZ + 1, git_object_id(target));
return reset(repo, target, to, reset_type, checkout_opts);
}
int git_reset_from_annotated(
......
......@@ -239,10 +239,10 @@ void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void)
cl_repo_set_bool(g_repo, "core.autocrlf", false);
git_repository_index(&index, g_repo);
cl_git_pass(git_repository_index(&index, g_repo));
tick_index(index);
git_checkout_head(g_repo, &opts);
cl_git_pass(git_checkout_head(g_repo, &opts));
cl_assert((entry = git_index_get_bypath(index, "all-lf", 0)) != NULL);
cl_assert(entry->file_size == strlen(ALL_LF_TEXT_RAW));
......
#include "clar_libgit2.h"
#include "diff_helpers.h"
#include "repository.h"
#include "index.h"
#include "git2/sys/diff.h"
#include "../checkout/checkout_helpers.h"
......@@ -2004,7 +2005,9 @@ void test_diff_workdir__only_writes_index_when_necessary(void)
git_diff *diff = NULL;
git_reference *head;
git_object *head_object;
git_oid initial, first, second;
unsigned char initial[GIT_HASH_SHA1_SIZE],
first[GIT_HASH_SHA1_SIZE],
second[GIT_HASH_SHA1_SIZE];
git_str path = GIT_STR_INIT;
struct stat st;
struct p_timeval times[2];
......@@ -2019,7 +2022,7 @@ void test_diff_workdir__only_writes_index_when_necessary(void)
cl_git_pass(git_reset(g_repo, head_object, GIT_RESET_HARD, NULL));
git_oid_cpy(&initial, git_index_checksum(index));
memcpy(initial, git_index__checksum(index), GIT_HASH_SHA1_SIZE);
/* update the index timestamp to avoid raciness */
cl_must_pass(p_stat("status/.git/index", &st));
......@@ -2035,8 +2038,8 @@ void test_diff_workdir__only_writes_index_when_necessary(void)
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
git_diff_free(diff);
git_oid_cpy(&first, git_index_checksum(index));
cl_assert(!git_oid_equal(&initial, &first));
memcpy(first, git_index__checksum(index), GIT_HASH_SHA1_SIZE);
cl_assert(memcmp(initial, first, GIT_HASH_SHA1_SIZE) != 0);
/* touch all the files so stat times are different */
cl_git_pass(git_str_sets(&path, "status"));
......@@ -2046,8 +2049,8 @@ void test_diff_workdir__only_writes_index_when_necessary(void)
git_diff_free(diff);
/* ensure the second diff did update the index */
git_oid_cpy(&second, git_index_checksum(index));
cl_assert(!git_oid_equal(&first, &second));
memcpy(second, git_index__checksum(index), GIT_HASH_SHA1_SIZE);
cl_assert(memcmp(first, second, GIT_HASH_SHA1_SIZE) != 0);
git_str_dispose(&path);
git_object_free(head_object);
......
......@@ -6,7 +6,7 @@
#include "commit_graph.h"
#include "futils.h"
void test_graph_commit_graph__parse(void)
void test_graph_commitgraph__parse(void)
{
git_repository *repo;
struct git_commit_graph_file *file;
......@@ -50,7 +50,7 @@ void test_graph_commit_graph__parse(void)
git_str_dispose(&commit_graph_path);
}
void test_graph_commit_graph__parse_octopus_merge(void)
void test_graph_commitgraph__parse_octopus_merge(void)
{
git_repository *repo;
struct git_commit_graph_file *file;
......@@ -91,7 +91,7 @@ void test_graph_commit_graph__parse_octopus_merge(void)
git_str_dispose(&commit_graph_path);
}
void test_graph_commit_graph__writer(void)
void test_graph_commitgraph__writer(void)
{
git_repository *repo;
git_commit_graph_writer *w = NULL;
......
......@@ -169,8 +169,7 @@ void test_pack_indexer__fix_thin(void)
cl_assert_equal_i(stats.indexed_objects, 2);
cl_assert_equal_i(stats.local_objects, 1);
git_oid_fromstr(&should_id, "fefdb2d740a3a6b6c03a0c7d6ce431c6d5810e13");
cl_assert_equal_oid(&should_id, git_indexer_hash(idx));
cl_assert_equal_s("fefdb2d740a3a6b6c03a0c7d6ce431c6d5810e13", git_indexer_name(idx));
git_indexer_free(idx);
git_odb_free(odb);
......
......@@ -5,6 +5,7 @@
#include "iterator.h"
#include "vector.h"
#include "posix.h"
#include "hash.h"
static git_repository *_repo;
static git_revwalk *_revwalker;
......@@ -98,8 +99,8 @@ void test_pack_packbuilder__create_pack(void)
git_indexer_progress stats;
git_str buf = GIT_STR_INIT, path = GIT_STR_INIT;
git_hash_ctx ctx;
git_oid hash;
char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0';
unsigned char hash[GIT_HASH_SHA1_SIZE];
char hex[(GIT_HASH_SHA1_SIZE * 2) + 1];
seed_packbuilder();
......@@ -107,8 +108,7 @@ void test_pack_packbuilder__create_pack(void)
cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats));
cl_git_pass(git_indexer_commit(_indexer, &stats));
git_oid_fmt(hex, git_indexer_hash(_indexer));
git_str_printf(&path, "pack-%s.pack", hex);
git_str_printf(&path, "pack-%s.pack", git_indexer_name(_indexer));
/*
* By default, packfiles are created with only one thread.
......@@ -128,27 +128,22 @@ void test_pack_packbuilder__create_pack(void)
cl_git_pass(git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1));
cl_git_pass(git_hash_update(&ctx, buf.ptr, buf.size));
cl_git_pass(git_hash_final(hash.id, &ctx));
cl_git_pass(git_hash_final(hash, &ctx));
git_hash_ctx_cleanup(&ctx);
git_str_dispose(&path);
git_str_dispose(&buf);
git_oid_fmt(hex, &hash);
git_hash_fmt(hex, hash, GIT_HASH_SHA1_SIZE);
cl_assert_equal_s(hex, "5d410bdf97cf896f9007681b92868471d636954b");
}
void test_pack_packbuilder__get_hash(void)
void test_pack_packbuilder__get_name(void)
{
char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0';
seed_packbuilder();
cl_git_pass(git_packbuilder_write(_packbuilder, ".", 0, NULL, NULL));
git_oid_fmt(hex, git_packbuilder_hash(_packbuilder));
cl_assert_equal_s(hex, "7f5fa362c664d68ba7221259be1cbd187434b2f0");
cl_assert_equal_s("7f5fa362c664d68ba7221259be1cbd187434b2f0", git_packbuilder_name(_packbuilder));
}
void test_pack_packbuilder__write_default_path(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment