summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c143
1 files changed, 76 insertions, 67 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 0d0314439..3deb0329c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -103,13 +103,14 @@ int git_buf_grow(git_buf *buffer, size_t target_size)
int git_buf_grow_by(git_buf *buffer, size_t additional_size)
{
- if (GIT_ALLOC_OVERFLOW_ADD(buffer->size, additional_size)) {
+ size_t newsize;
+
+ if (GIT_ADD_SIZET_OVERFLOW(&newsize, buffer->size, additional_size)) {
buffer->ptr = git_buf__oom;
return -1;
}
- return git_buf_try_grow(
- buffer, buffer->size + additional_size, true, true);
+ return git_buf_try_grow(buffer, newsize, true, true);
}
void git_buf_free(git_buf *buf)
@@ -146,12 +147,14 @@ void git_buf_clear(git_buf *buf)
int git_buf_set(git_buf *buf, const void *data, size_t len)
{
+ size_t alloclen;
+
if (len == 0 || data == NULL) {
git_buf_clear(buf);
} else {
if (data != buf->ptr) {
- GITERR_CHECK_ALLOC_ADD(len, 1);
- ENSURE_SIZE(buf, len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+ ENSURE_SIZE(buf, alloclen);
memmove(buf->ptr, data, len);
}
@@ -180,8 +183,9 @@ int git_buf_sets(git_buf *buf, const char *string)
int git_buf_putc(git_buf *buf, char c)
{
- GITERR_CHECK_ALLOC_ADD(buf->size, 2);
- ENSURE_SIZE(buf, buf->size + 2);
+ size_t new_size;
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, 2);
+ ENSURE_SIZE(buf, new_size);
buf->ptr[buf->size++] = c;
buf->ptr[buf->size] = '\0';
return 0;
@@ -189,9 +193,10 @@ int git_buf_putc(git_buf *buf, char c)
int git_buf_putcn(git_buf *buf, char c, size_t len)
{
- GITERR_CHECK_ALLOC_ADD(buf->size, len);
- GITERR_CHECK_ALLOC_ADD(buf->size + len, 1);
- ENSURE_SIZE(buf, buf->size + len + 1);
+ size_t new_size;
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
memset(buf->ptr + buf->size, c, len);
buf->size += len;
buf->ptr[buf->size] = '\0';
@@ -201,10 +206,13 @@ int git_buf_putcn(git_buf *buf, char c, size_t len)
int git_buf_put(git_buf *buf, const char *data, size_t len)
{
if (len) {
+ size_t new_size;
+
assert(data);
- GITERR_CHECK_ALLOC_ADD(buf->size, len);
- GITERR_CHECK_ALLOC_ADD(buf->size + len, 1);
- ENSURE_SIZE(buf, buf->size + len + 1);
+
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
memmove(buf->ptr + buf->size, data, len);
buf->size += len;
buf->ptr[buf->size] = '\0';
@@ -226,12 +234,13 @@ int git_buf_encode_base64(git_buf *buf, const char *data, size_t len)
size_t extra = len % 3;
uint8_t *write, a, b, c;
const uint8_t *read = (const uint8_t *)data;
- size_t blocks = (len / 3) + !!extra;
+ size_t blocks = (len / 3) + !!extra, alloclen;
+
+ GITERR_CHECK_ALLOC_ADD(&blocks, blocks, 1);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 4);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size);
- GITERR_CHECK_ALLOC_MULTIPLY(blocks, 4);
- GITERR_CHECK_ALLOC_ADD(buf->size, 4 * blocks);
- GITERR_CHECK_ALLOC_ADD(buf->size + 4 * blocks, 1);
- ENSURE_SIZE(buf, buf->size + 4 * blocks + 1);
+ ENSURE_SIZE(buf, alloclen);
write = (uint8_t *)&buf->ptr[buf->size];
/* convert each run of 3 bytes into 4 output bytes */
@@ -282,12 +291,12 @@ int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len)
{
size_t i;
int8_t a, b, c, d;
- size_t orig_size = buf->size;
+ size_t orig_size = buf->size, new_size;
assert(len % 4 == 0);
- GITERR_CHECK_ALLOC_ADD(buf->size, len / 4 * 3);
- GITERR_CHECK_ALLOC_ADD(buf->size + (len / 4 * 3), 1);
- ENSURE_SIZE(buf, buf->size + (len / 4 * 3) + 1);
+ GITERR_CHECK_ALLOC_ADD(&new_size, (len / 4 * 3), buf->size);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
for (i = 0; i < len; i += 4) {
if ((a = BASE64_DECODE_VALUE(base64[i])) < 0 ||
@@ -315,12 +324,13 @@ static const char b85str[] =
int git_buf_encode_base85(git_buf *buf, const char *data, size_t len)
{
- size_t blocks = (len / 4) + !!(len % 4);
+ size_t blocks = (len / 4) + !!(len % 4), alloclen;
- GITERR_CHECK_ALLOC_MULTIPLY(blocks, 5);
- GITERR_CHECK_ALLOC_ADD(buf->size, 5 * blocks);
- GITERR_CHECK_ALLOC_ADD(buf->size + 5 * blocks, 1);
- ENSURE_SIZE(buf, buf->size + blocks * 5 + 1);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 5);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+
+ ENSURE_SIZE(buf, alloclen);
while (len) {
uint32_t acc = 0;
@@ -353,15 +363,11 @@ int git_buf_encode_base85(git_buf *buf, const char *data, size_t len)
int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
{
- size_t expected_size = strlen(format);
+ size_t expected_size, new_size;
int len;
- GITERR_CHECK_ALLOC_MULTIPLY(expected_size, 2);
- expected_size *= 2;
-
- GITERR_CHECK_ALLOC_ADD(expected_size, buf->size);
- expected_size += buf->size;
-
+ GITERR_CHECK_ALLOC_MULTIPLY(&expected_size, strlen(format), 2);
+ GITERR_CHECK_ALLOC_ADD(&expected_size, expected_size, buf->size);
ENSURE_SIZE(buf, expected_size);
while (1) {
@@ -387,9 +393,9 @@ int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
break;
}
- GITERR_CHECK_ALLOC_ADD(buf->size, len);
- GITERR_CHECK_ALLOC_ADD(buf->size + len, 1);
- ENSURE_SIZE(buf, buf->size + len + 1);
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
}
return 0;
@@ -516,9 +522,11 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
continue;
segment_len = strlen(segment);
- total_size += segment_len;
+
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, segment_len);
+
if (segment_len == 0 || segment[segment_len - 1] != separator)
- ++total_size; /* space for separator */
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
}
va_end(ap);
@@ -526,8 +534,8 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
if (total_size == 0)
return 0;
- GITERR_CHECK_ALLOC_ADD(total_size, 1);
- if (git_buf_grow_by(buf, total_size + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
+ if (git_buf_grow_by(buf, total_size) < 0)
return -1;
out = buf->ptr + buf->size;
@@ -588,6 +596,7 @@ int git_buf_join(
{
size_t strlen_a = str_a ? strlen(str_a) : 0;
size_t strlen_b = strlen(str_b);
+ size_t alloc_len;
int need_sep = 0;
ssize_t offset_a = -1;
@@ -605,10 +614,10 @@ int git_buf_join(
if (str_a >= buf->ptr && str_a < buf->ptr + buf->size)
offset_a = str_a - buf->ptr;
- GITERR_CHECK_ALLOC_ADD(strlen_a, strlen_b);
- GITERR_CHECK_ALLOC_ADD(strlen_a + strlen_b, need_sep);
- GITERR_CHECK_ALLOC_ADD(strlen_a + strlen_b + need_sep, 1);
- if (git_buf_grow(buf, strlen_a + strlen_b + need_sep + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, strlen_a, strlen_b);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, need_sep);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+ if (git_buf_grow(buf, alloc_len) < 0)
return -1;
assert(buf->ptr);
@@ -636,7 +645,10 @@ int git_buf_join3(
const char *str_b,
const char *str_c)
{
- size_t len_a = strlen(str_a), len_b = strlen(str_b), len_c = strlen(str_c);
+ size_t len_a = strlen(str_a),
+ len_b = strlen(str_b),
+ len_c = strlen(str_c),
+ len_total;
int sep_a = 0, sep_b = 0;
char *tgt;
@@ -656,12 +668,12 @@ int git_buf_join3(
sep_b = (str_b[len_b - 1] != separator);
}
- GITERR_CHECK_ALLOC_ADD(len_a, sep_a);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a, len_b);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a + len_b, sep_b);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a + len_b + sep_b, len_c);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a + len_b + sep_b + len_c, 1);
- if (git_buf_grow(buf, len_a + sep_a + len_b + sep_b + len_c + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_a, sep_a);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_b);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, sep_b);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_c);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, 1);
+ if (git_buf_grow(buf, len_total) < 0)
return -1;
tgt = buf->ptr;
@@ -714,28 +726,25 @@ int git_buf_splice(
const char *data,
size_t nb_to_insert)
{
- size_t new_size;
+ char *splice_loc;
+ size_t new_size, alloc_size;
- assert(buf &&
- where <= git_buf_len(buf) &&
- where + nb_to_remove <= git_buf_len(buf));
+ assert(buf && where <= buf->size && nb_to_remove <= buf->size - where);
+
+ splice_loc = buf->ptr + where;
/* Ported from git.git
* https://github.com/git/git/blob/16eed7c/strbuf.c#L159-176
*/
- new_size = buf->size - nb_to_remove;
-
- GITERR_CHECK_ALLOC_ADD(new_size, nb_to_insert);
- new_size += nb_to_insert;
-
- GITERR_CHECK_ALLOC_ADD(new_size, 1);
- ENSURE_SIZE(buf, new_size + 1);
+ GITERR_CHECK_ALLOC_ADD(&new_size, (buf->size - nb_to_remove), nb_to_insert);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, new_size, 1);
+ ENSURE_SIZE(buf, alloc_size);
- memmove(buf->ptr + where + nb_to_insert,
- buf->ptr + where + nb_to_remove,
- buf->size - where - nb_to_remove);
+ memmove(splice_loc + nb_to_insert,
+ splice_loc + nb_to_remove,
+ buf->size - where - nb_to_remove);
- memcpy(buf->ptr + where, data, nb_to_insert);
+ memcpy(splice_loc, data, nb_to_insert);
buf->size = new_size;
buf->ptr[buf->size] = '\0';