void test_buf_oom__grow_by(void) { git_buf buf = GIT_BUF_INIT; buf.size = SIZE_MAX-10; cl_assert(git_buf_grow_by(&buf, 50) == -1); cl_assert(git_buf_oom(&buf)); }
void test_buf_basic__resize_incremental(void) { git_buf buf1 = GIT_BUF_INIT; /* Presently, asking for 6 bytes will round up to 8. */ cl_git_pass(git_buf_puts(&buf1, "Hello")); cl_assert_equal_i(5, buf1.size); cl_assert_equal_i(8, buf1.asize); /* Ensure an additional byte does not realloc. */ cl_git_pass(git_buf_grow_by(&buf1, 1)); cl_assert_equal_i(5, buf1.size); cl_assert_equal_i(8, buf1.asize); /* But requesting many does. */ cl_git_pass(git_buf_grow_by(&buf1, 16)); cl_assert_equal_i(5, buf1.size); cl_assert(buf1.asize > 8); git_buf_dispose(&buf1); }
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf) { git_buf str = GIT_BUF_INIT; char oid[GIT_OID_HEXSZ +1] = {0}; size_t len; /* Prefer multi_ack_detailed */ if (caps->multi_ack_detailed) git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " "); else if (caps->multi_ack) git_buf_puts(&str, GIT_CAP_MULTI_ACK " "); /* Prefer side-band-64k if the server supports both */ if (caps->side_band_64k) git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K); else if (caps->side_band) git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND); if (caps->include_tag) git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " "); if (caps->thin_pack) git_buf_puts(&str, GIT_CAP_THIN_PACK " "); if (caps->ofs_delta) git_buf_puts(&str, GIT_CAP_OFS_DELTA " "); if (git_buf_oom(&str)) return -1; len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + git_buf_len(&str) + 1 /* LF */; if (len > 0xffff) { giterr_set(GITERR_NET, "tried to produce packet with invalid length %" PRIuZ, len); return -1; } git_buf_grow_by(buf, len); git_oid_fmt(oid, &head->oid); git_buf_printf(buf, "%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str)); git_buf_dispose(&str); GITERR_CHECK_ALLOC_BUF(buf); return 0; }
int git_buf_text_puts_escaped( git_buf *buf, const char *string, const char *esc_chars, const char *esc_with) { const char *scan; size_t total = 0, esc_len = strlen(esc_with), count, alloclen; if (!string) return 0; for (scan = string; *scan; ) { /* count run of non-escaped characters */ count = strcspn(scan, esc_chars); total += count; scan += count; /* count run of escaped characters */ count = strspn(scan, esc_chars); total += count * (esc_len + 1); scan += count; } GITERR_CHECK_ALLOC_ADD(&alloclen, total, 1); if (git_buf_grow_by(buf, alloclen) < 0) return -1; for (scan = string; *scan; ) { count = strcspn(scan, esc_chars); memmove(buf->ptr + buf->size, scan, count); scan += count; buf->size += count; for (count = strspn(scan, esc_chars); count > 0; --count) { /* copy escape sequence */ memmove(buf->ptr + buf->size, esc_with, esc_len); buf->size += esc_len; /* copy character to be escaped */ buf->ptr[buf->size] = *scan; buf->size++; scan++; } } buf->ptr[buf->size] = '\0'; return 0; }
int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src) { const char *start = src->ptr; const char *end = start + src->size; const char *scan = start; const char *next = memchr(scan, '\n', src->size); size_t alloclen; assert(tgt != src); if (!next) return git_buf_set(tgt, src->ptr, src->size); /* attempt to reduce reallocs while in the loop */ GITERR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4); GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1); if (git_buf_grow(tgt, alloclen) < 0) return -1; tgt->size = 0; for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) { size_t copylen = next - scan; /* if we find mixed line endings, bail */ if (next > start && next[-1] == '\r') { git_buf_free(tgt); return GIT_PASSTHROUGH; } GITERR_CHECK_ALLOC_ADD(&alloclen, copylen, 3); if (git_buf_grow_by(tgt, alloclen) < 0) return -1; if (next > scan) { memcpy(tgt->ptr + tgt->size, scan, copylen); tgt->size += copylen; } tgt->ptr[tgt->size++] = '\r'; tgt->ptr[tgt->size++] = '\n'; } tgt->ptr[tgt->size] = '\0'; return git_buf_put(tgt, scan, end - scan); }