summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PROJECTS.md3
-rw-r--r--include/git2/oid.h12
-rw-r--r--src/global.h1
-rw-r--r--src/oid.c8
-rw-r--r--src/oid.h11
-rw-r--r--src/transports/http.c24
-rw-r--r--tests/object/raw/compare.c5
-rw-r--r--tests/online/push_util.c6
-rw-r--r--tests/stash/save.c8
9 files changed, 53 insertions, 25 deletions
diff --git a/PROJECTS.md b/PROJECTS.md
index 5164d95b6..d69988759 100644
--- a/PROJECTS.md
+++ b/PROJECTS.md
@@ -53,9 +53,6 @@ These are good small projects to get started with libgit2.
* Submit a PR to clarify documentation! While we do try to document all of
the APIs, your fresh eyes on the documentation will find areas that are
confusing much more easily.
-* Add support for the symref protocol extension, so we don't guess
- what the remote's default branch is
- [#2006](https://github.com/libgit2/libgit2/issues/2006)
If none of these appeal to you, take a look at our issues list to see if
there are any unresolved issues you'd like to jump in on.
diff --git a/include/git2/oid.h b/include/git2/oid.h
index 1cfd4e5e2..db2f3af70 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -116,13 +116,17 @@ GIT_EXTERN(void) git_oid_nfmt(char *out, size_t n, const git_oid *id);
GIT_EXTERN(void) git_oid_pathfmt(char *out, const git_oid *id);
/**
- * Format a git_oid into a newly allocated c-string.
+ * Format a git_oid into a statically allocated c-string.
+ *
+ * The c-string is owned by the library and should not be freed
+ * by the user. If libgit2 is built with thread support, the string
+ * will be stored in TLS (i.e. one buffer per thread) to allow for
+ * concurrent calls of the function.
*
* @param id the oid structure to format
- * @return the c-string; NULL if memory is exhausted. Caller must
- * deallocate the string with git__free().
+ * @return the c-string
*/
-GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id);
+GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
/**
* Format a git_oid into a buffer as a hex format c-string.
diff --git a/src/global.h b/src/global.h
index 745df3e4a..106504628 100644
--- a/src/global.h
+++ b/src/global.h
@@ -13,6 +13,7 @@
typedef struct {
git_error *last_error;
git_error error_t;
+ char oid_fmt[41];
} git_global_st;
#ifdef GIT_SSL
diff --git a/src/oid.c b/src/oid.c
index b640cadd1..969931d04 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -8,6 +8,7 @@
#include "common.h"
#include "git2/oid.h"
#include "repository.h"
+#include "global.h"
#include <string.h>
#include <limits.h>
@@ -99,6 +100,13 @@ void git_oid_pathfmt(char *str, const git_oid *oid)
str = fmt_one(str, oid->id[i]);
}
+char *git_oid_tostr_s(const git_oid *oid)
+{
+ char *str = GIT_GLOBAL->oid_fmt;
+ git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid);
+ return str;
+}
+
char *git_oid_allocfmt(const git_oid *oid)
{
char *str = git__malloc(GIT_OID_HEXSZ + 1);
diff --git a/src/oid.h b/src/oid.h
index cfe7ca1b2..aa1f0bfdc 100644
--- a/src/oid.h
+++ b/src/oid.h
@@ -9,6 +9,17 @@
#include "git2/oid.h"
+/**
+ * Format a git_oid into a newly allocated c-string.
+ *
+ * The c-string is owned by the caller and needs to be manually freed.
+ *
+ * @param id the oid structure to format
+ * @return the c-string; NULL if memory is exhausted. Caller must
+ * deallocate the string with git__free().
+ */
+char *git_oid_allocfmt(const git_oid *id);
+
GIT_INLINE(int) git_oid__hashcmp(const unsigned char *sha1, const unsigned char *sha2)
{
int i;
diff --git a/src/transports/http.c b/src/transports/http.c
index 5c5e5d391..f9df53b71 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -607,7 +607,23 @@ replay:
}
while (!*bytes_read && !t->parse_finished) {
- t->parse_buffer.offset = 0;
+ size_t data_offset;
+
+ /*
+ * Make the parse_buffer think it's as full of data as
+ * the buffer, so it won't try to recv more data than
+ * we can put into it.
+ *
+ * data_offset is the actual data offset from which we
+ * should tell the parser to start reading.
+ */
+ if (buf_size >= t->parse_buffer.len) {
+ t->parse_buffer.offset = 0;
+ } else {
+ t->parse_buffer.offset = t->parse_buffer.len - buf_size;
+ }
+
+ data_offset = t->parse_buffer.offset;
if (gitno_recv(&t->parse_buffer) < 0)
return -1;
@@ -628,8 +644,8 @@ replay:
bytes_parsed = http_parser_execute(&t->parser,
&t->settings,
- t->parse_buffer.data,
- t->parse_buffer.offset);
+ t->parse_buffer.data + data_offset,
+ t->parse_buffer.offset - data_offset);
t->parser.data = NULL;
@@ -647,7 +663,7 @@ replay:
if (t->parse_error < 0)
return -1;
- if (bytes_parsed != t->parse_buffer.offset) {
+ if (bytes_parsed != t->parse_buffer.offset - data_offset) {
giterr_set(GITERR_NET,
"HTTP parser error: %s",
http_errno_description((enum http_errno)t->parser.http_errno));
diff --git a/tests/object/raw/compare.c b/tests/object/raw/compare.c
index 1c9ce4b81..56c016b72 100644
--- a/tests/object/raw/compare.c
+++ b/tests/object/raw/compare.c
@@ -90,7 +90,7 @@ void test_object_raw_compare__compare_fmt_oids(void)
cl_assert_equal_s(exp, out);
}
-void test_object_raw_compare__compare_allocfmt_oids(void)
+void test_object_raw_compare__compare_static_oids(void)
{
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
git_oid in;
@@ -98,10 +98,9 @@ void test_object_raw_compare__compare_allocfmt_oids(void)
cl_git_pass(git_oid_fromstr(&in, exp));
- out = git_oid_allocfmt(&in);
+ out = git_oid_tostr_s(&in);
cl_assert(out);
cl_assert_equal_s(exp, out);
- git__free(out);
}
void test_object_raw_compare__compare_pathfmt_oids(void)
diff --git a/tests/online/push_util.c b/tests/online/push_util.c
index 038c144db..68e71eacc 100644
--- a/tests/online/push_util.c
+++ b/tests/online/push_util.c
@@ -110,9 +110,8 @@ failed:
git_buf_puts(&msg, "Expected and actual refs differ:\nEXPECTED:\n");
for(i = 0; i < expected_refs_len; i++) {
- cl_assert(oid_str = git_oid_allocfmt(expected_refs[i].oid));
+ oid_str = git_oid_tostr_s(expected_refs[i].oid);
cl_git_pass(git_buf_printf(&msg, "%s = %s\n", expected_refs[i].name, oid_str));
- git__free(oid_str);
}
git_buf_puts(&msg, "\nACTUAL:\n");
@@ -121,9 +120,8 @@ failed:
if (master_present && !strcmp(actual->name, "refs/heads/master"))
continue;
- cl_assert(oid_str = git_oid_allocfmt(&actual->oid));
+ oid_str = git_oid_tostr_s(&actual->oid);
cl_git_pass(git_buf_printf(&msg, "%s = %s\n", actual->name, oid_str));
- git__free(oid_str);
}
cl_fail(git_buf_cstr(&msg));
diff --git a/tests/stash/save.c b/tests/stash/save.c
index 87c6d7e0f..3b301bfc0 100644
--- a/tests/stash/save.c
+++ b/tests/stash/save.c
@@ -227,18 +227,12 @@ void test_stash_save__can_stash_against_a_detached_head(void)
void test_stash_save__stashing_updates_the_reflog(void)
{
- char *sha;
-
assert_object_oid("refs/stash@{0}", NULL, GIT_OBJ_COMMIT);
cl_git_pass(git_stash_save(&stash_tip_oid, repo, signature, NULL, GIT_STASH_DEFAULT));
- sha = git_oid_allocfmt(&stash_tip_oid);
-
- assert_object_oid("refs/stash@{0}", sha, GIT_OBJ_COMMIT);
+ assert_object_oid("refs/stash@{0}", git_oid_tostr_s(&stash_tip_oid), GIT_OBJ_COMMIT);
assert_object_oid("refs/stash@{1}", NULL, GIT_OBJ_COMMIT);
-
- git__free(sha);
}
void test_stash_save__cannot_stash_when_there_are_no_local_change(void)