summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-04-23 00:07:06 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2023-04-25 10:34:31 +0100
commit72139ef289383dafeea355ace222359c48d98563 (patch)
tree9d853a64b31ef18a1dc1456b8b30a4e958c599d8
parent3853ba8de64a0e774c6e73aacb5831707f841621 (diff)
downloadlibgit2-72139ef289383dafeea355ace222359c48d98563.tar.gz
shallow: don't assume SHA1
-rw-r--r--src/libgit2/repository.c6
-rw-r--r--src/libgit2/transports/smart_pkt.c66
2 files changed, 46 insertions, 26 deletions
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c
index 3b6ecae24..a60fb23fa 100644
--- a/src/libgit2/repository.c
+++ b/src/libgit2/repository.c
@@ -3670,13 +3670,14 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro
{
git_filebuf file = GIT_FILEBUF_INIT;
git_str path = GIT_STR_INIT;
+ char oid_str[GIT_OID_MAX_HEXSIZE + 1];
size_t idx;
git_oid *oid;
int filebuf_hash, error = 0;
GIT_ASSERT_ARG(repo);
- filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(GIT_OID_SHA1));
+ filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(repo->oid_type));
GIT_ASSERT(filebuf_hash);
if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0)
@@ -3686,7 +3687,8 @@ int git_repository__shallow_roots_write(git_repository *repo, git_array_oid_t ro
goto on_error;
git_array_foreach(roots, idx, oid) {
- git_filebuf_write(&file, git_oid_tostr_s(oid), GIT_OID_SHA1_HEXSIZE);
+ git_oid_tostr(oid_str, sizeof(oid_str), oid);
+ git_filebuf_write(&file, oid_str, git_oid_hexsize(repo->oid_type));
git_filebuf_write(&file, "\n", 1);
}
diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c
index e8c87cb8d..3199c18f0 100644
--- a/src/libgit2/transports/smart_pkt.c
+++ b/src/libgit2/transports/smart_pkt.c
@@ -44,9 +44,14 @@ static int flush_pkt(git_pkt **out)
}
/* the rest of the line will be useful for multi_ack and multi_ack_detailed */
-static int ack_pkt(git_pkt **out, const char *line, size_t len)
+static int ack_pkt(
+ git_pkt **out,
+ const char *line,
+ size_t len,
+ git_pkt_parse_data *data)
{
git_pkt_ack *pkt;
+ size_t oid_hexsize = git_oid_hexsize(data->oid_type);
pkt = git__calloc(1, sizeof(git_pkt_ack));
GIT_ERROR_CHECK_ALLOC(pkt);
@@ -57,11 +62,11 @@ static int ack_pkt(git_pkt **out, const char *line, size_t len)
line += 4;
len -= 4;
- if (len < GIT_OID_SHA1_HEXSIZE ||
- git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1) < 0)
+ if (len < oid_hexsize ||
+ git_oid__fromstr(&pkt->oid, line, data->oid_type) < 0)
goto out_err;
- line += GIT_OID_SHA1_HEXSIZE;
- len -= GIT_OID_SHA1_HEXSIZE;
+ line += oid_hexsize;
+ len -= oid_hexsize;
if (len && line[0] == ' ') {
line++;
@@ -436,9 +441,14 @@ static int unpack_pkt(git_pkt **out, const char *line, size_t len)
return 0;
}
-static int shallow_pkt(git_pkt **out, const char *line, size_t len)
+static int shallow_pkt(
+ git_pkt **out,
+ const char *line,
+ size_t len,
+ git_pkt_parse_data *data)
{
git_pkt_shallow *pkt;
+ size_t oid_hexsize = git_oid_hexsize(data->oid_type);
pkt = git__calloc(1, sizeof(git_pkt_shallow));
GIT_ERROR_CHECK_ALLOC(pkt);
@@ -451,13 +461,14 @@ static int shallow_pkt(git_pkt **out, const char *line, size_t len)
line += 8;
len -= 8;
- if (len >= GIT_OID_SHA1_HEXSIZE) {
- git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1);
- line += GIT_OID_SHA1_HEXSIZE + 1;
- len -= GIT_OID_SHA1_HEXSIZE + 1;
- }
+ if (len != oid_hexsize)
+ goto out_err;
- *out = (git_pkt *) pkt;
+ git_oid__fromstr(&pkt->oid, line, data->oid_type);
+ line += oid_hexsize + 1;
+ len -= oid_hexsize + 1;
+
+ *out = (git_pkt *)pkt;
return 0;
@@ -467,9 +478,14 @@ out_err:
return -1;
}
-static int unshallow_pkt(git_pkt **out, const char *line, size_t len)
+static int unshallow_pkt(
+ git_pkt **out,
+ const char *line,
+ size_t len,
+ git_pkt_parse_data *data)
{
git_pkt_shallow *pkt;
+ size_t oid_hexsize = git_oid_hexsize(data->oid_type);
pkt = git__calloc(1, sizeof(git_pkt_shallow));
GIT_ERROR_CHECK_ALLOC(pkt);
@@ -482,11 +498,12 @@ static int unshallow_pkt(git_pkt **out, const char *line, size_t len)
line += 10;
len -= 10;
- if (len >= GIT_OID_SHA1_HEXSIZE) {
- git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1);
- line += GIT_OID_SHA1_HEXSIZE + 1;
- len -= GIT_OID_SHA1_HEXSIZE + 1;
- }
+ if (len != oid_hexsize)
+ goto out_err;
+
+ git_oid__fromstr(&pkt->oid, line, data->oid_type);
+ line += oid_hexsize + 1;
+ len -= oid_hexsize + 1;
*out = (git_pkt *) pkt;
@@ -615,7 +632,7 @@ int git_pkt_parse_line(
else if (*line == GIT_SIDE_BAND_ERROR)
error = sideband_error_pkt(pkt, line, len);
else if (!git__prefixncmp(line, len, "ACK"))
- error = ack_pkt(pkt, line, len);
+ error = ack_pkt(pkt, line, len, data);
else if (!git__prefixncmp(line, len, "NAK"))
error = nak_pkt(pkt);
else if (!git__prefixncmp(line, len, "ERR"))
@@ -629,9 +646,9 @@ int git_pkt_parse_line(
else if (!git__prefixncmp(line, len, "unpack"))
error = unpack_pkt(pkt, line, len);
else if (!git__prefixcmp(line, "shallow"))
- error = shallow_pkt(pkt, line, len);
+ error = shallow_pkt(pkt, line, len, data);
else if (!git__prefixcmp(line, "unshallow"))
- error = unshallow_pkt(pkt, line, len);
+ error = unshallow_pkt(pkt, line, len, data);
else
error = ref_pkt(pkt, line, len, data);
@@ -788,12 +805,13 @@ int git_pkt_buffer_wants(
/* Tell the server about our shallow objects */
for (i = 0; i < git_shallowarray_count(wants->shallow_roots); i++) {
- char oid[GIT_OID_SHA1_HEXSIZE];
+ char oid[GIT_OID_MAX_HEXSIZE + 1];
git_str shallow_buf = GIT_STR_INIT;
- git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i));
+ git_oid_tostr(oid, GIT_OID_MAX_HEXSIZE + 1,
+ git_shallowarray_get(wants->shallow_roots, i));
git_str_puts(&shallow_buf, "shallow ");
- git_str_put(&shallow_buf, oid, GIT_OID_SHA1_HEXSIZE);
+ git_str_puts(&shallow_buf, oid);
git_str_putc(&shallow_buf, '\n');
git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf));