summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-02-10 23:55:07 -0500
committerEdward Thomson <ethomson@edwardthomson.com>2015-02-12 22:54:47 -0500
commit4aa664ae3953d99c2ae4cd769f02818bc122eebc (patch)
tree7316e3d7febcbcde19dd4844af9503f4c6d57d69 /src
parent3603cb0978b7ef21ff9cd63693ebd6d27bc2bc53 (diff)
downloadlibgit2-4aa664ae3953d99c2ae4cd769f02818bc122eebc.tar.gz
git_buf_grow_by: increase buf asize incrementally
Introduce `git_buf_grow_by` to incrementally increase the size of a `git_buf`, performing an overflow calculation on the growth.
Diffstat (limited to 'src')
-rw-r--r--src/buf_text.c13
-rw-r--r--src/buffer.c17
-rw-r--r--src/buffer.h12
-rw-r--r--src/transports/smart_pkt.c2
-rw-r--r--src/zstream.c3
5 files changed, 32 insertions, 15 deletions
diff --git a/src/buf_text.c b/src/buf_text.c
index ace54d725..08b86f4cc 100644
--- a/src/buf_text.c
+++ b/src/buf_text.c
@@ -29,9 +29,8 @@ int git_buf_text_puts_escaped(
scan += count;
}
- GITERR_CHECK_ALLOC_ADD(buf->size, total);
- GITERR_CHECK_ALLOC_ADD(buf->size + total, 1);
- if (git_buf_grow(buf, buf->size + total + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(total, 1);
+ if (git_buf_grow_by(buf, total + 1) < 0)
return -1;
for (scan = string; *scan; ) {
@@ -129,7 +128,6 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
size_t copylen = next - scan;
- size_t needsize;
/* if we find mixed line endings, bail */
if (next > start && next[-1] == '\r') {
@@ -137,11 +135,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
return GIT_PASSTHROUGH;
}
- GITERR_CHECK_ALLOC_ADD(tgt->size, copylen);
- GITERR_CHECK_ALLOC_ADD(tgt->size + copylen, 3);
- needsize = tgt->size + copylen + 3;
-
- if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0)
+ GITERR_CHECK_ALLOC_ADD(copylen, 3);
+ if (git_buf_grow_by(tgt, copylen + 3) < 0)
return -1;
if (next > scan) {
diff --git a/src/buffer.c b/src/buffer.c
index ee8bba4ec..8098bb1e7 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -101,6 +101,18 @@ int git_buf_grow(git_buf *buffer, size_t target_size)
return git_buf_try_grow(buffer, target_size, true, true);
}
+int git_buf_grow_by(git_buf *buffer, size_t additional_size)
+{
+ if (GIT_ALLOC_OVERFLOW_ADD(buffer->size, additional_size)) {
+ buffer->ptr = git_buf__oom;
+ giterr_set_oom();
+ return -1;
+ }
+
+ return git_buf_try_grow(
+ buffer, buffer->size + additional_size, true, true);
+}
+
void git_buf_free(git_buf *buf)
{
if (!buf) return;
@@ -515,9 +527,8 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
if (total_size == 0)
return 0;
- GITERR_CHECK_ALLOC_ADD(buf->size, total_size);
- GITERR_CHECK_ALLOC_ADD(buf->size + total_size, 1);
- if (git_buf_grow(buf, buf->size + total_size + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(total_size, 1);
+ if (git_buf_grow_by(buf, total_size + 1) < 0)
return -1;
out = buf->ptr + buf->size;
diff --git a/src/buffer.h b/src/buffer.h
index 8ee4b532c..52342e309 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -37,6 +37,18 @@ GIT_INLINE(bool) git_buf_is_allocated(const git_buf *buf)
extern void git_buf_init(git_buf *buf, size_t initial_size);
/**
+ * Resize the buffer allocation to make more space.
+ *
+ * This will attempt to grow the buffer to accommodate the additional size.
+ * It is similar to `git_buf_grow`, but performs the new size calculation,
+ * checking for overflow.
+ *
+ * Like `git_buf_grow`, if this is a user-supplied buffer, this will allocate
+ * a new buffer.
+ */
+extern int git_buf_grow_by(git_buf *buffer, size_t additional_size);
+
+/**
* Attempt to grow the buffer to hold at least `target_size` bytes.
*
* If the allocation fails, this will return an error. If `mark_oom` is true,
diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index 2f83e0d7b..ad81ad1b0 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -513,7 +513,7 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
len = (unsigned int)
(strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
git_buf_len(&str) + 1 /* LF */);
- git_buf_grow(buf, git_buf_len(buf) + len);
+ git_buf_grow_by(buf, len);
git_oid_fmt(oid, &head->oid);
git_buf_printf(buf, "%04xwant %s %s\n", len, oid, git_buf_cstr(&str));
git_buf_free(&str);
diff --git a/src/zstream.c b/src/zstream.c
index 06660e981..2130bc3ca 100644
--- a/src/zstream.c
+++ b/src/zstream.c
@@ -134,8 +134,7 @@ int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len)
while (!git_zstream_done(&zs)) {
size_t step = git_zstream_suggest_output_len(&zs), written;
- GITERR_CHECK_ALLOC_ADD(out->size, step);
- if ((error = git_buf_grow(out, out->size + step)) < 0)
+ if ((error = git_buf_grow_by(out, step)) < 0)
goto done;
written = out->asize - out->size;