]> git.ipfire.org Git - thirdparty/git.git/blobdiff - strbuf.c
strbuf_split: add a max parameter
[thirdparty/git.git] / strbuf.c
index bc3a0802ea7e7b1743602972de182391b4bf0b3f..74f661ec2b16a346ca18a83926584b91d112715b 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -63,7 +63,8 @@ void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
 
 void strbuf_grow(struct strbuf *sb, size_t extra)
 {
-       if (sb->len + extra + 1 <= sb->len)
+       if (unsigned_add_overflows(extra, 1) ||
+           unsigned_add_overflows(sb->len, extra + 1))
                die("you want to use way too much memory");
        if (!sb->alloc)
                sb->buf = NULL;
@@ -100,7 +101,7 @@ void strbuf_ltrim(struct strbuf *sb)
        sb->buf[sb->len] = '\0';
 }
 
-struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
+struct strbuf **strbuf_split_max(const struct strbuf *sb, int delim, int max)
 {
        int alloc = 2, pos = 0;
        char *n, *p;
@@ -111,7 +112,10 @@ struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
        p = n = sb->buf;
        while (n < sb->buf + sb->len) {
                int len;
-               n = memchr(n, delim, sb->len - (n - sb->buf));
+               if (max <= 0 || pos + 1 < max)
+                       n = memchr(n, delim, sb->len - (n - sb->buf));
+               else
+                       n = NULL;
                if (pos + 1 >= alloc) {
                        alloc = alloc * 2;
                        ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);
@@ -152,7 +156,7 @@ int strbuf_cmp(const struct strbuf *a, const struct strbuf *b)
 void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
                                   const void *data, size_t dlen)
 {
-       if (pos + len < pos)
+       if (unsigned_add_overflows(pos, len))
                die("you want to use way too much memory");
        if (pos > sb->len)
                die("`pos' is too far after the end of the buffer");
@@ -194,24 +198,29 @@ void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
 
 void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
 {
-       int len;
        va_list ap;
+       va_start(ap, fmt);
+       strbuf_vaddf(sb, fmt, ap);
+       va_end(ap);
+}
+
+void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
+{
+       int len;
+       va_list cp;
 
        if (!strbuf_avail(sb))
                strbuf_grow(sb, 64);
-       va_start(ap, fmt);
-       len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
-       va_end(ap);
+       va_copy(cp, ap);
+       len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, cp);
+       va_end(cp);
        if (len < 0)
-               die("your vsnprintf is broken");
+               die("BUG: your vsnprintf is broken (returned %d)", len);
        if (len > strbuf_avail(sb)) {
                strbuf_grow(sb, len);
-               va_start(ap, fmt);
                len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
-               va_end(ap);
-               if (len > strbuf_avail(sb)) {
-                       die("this should not happen, your snprintf is broken");
-               }
+               if (len > strbuf_avail(sb))
+                       die("BUG: your vsnprintf is broken (insatiable)");
        }
        strbuf_setlen(sb, sb->len + len);
 }
@@ -386,19 +395,3 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 
        return len;
 }
-
-int strbuf_branchname(struct strbuf *sb, const char *name)
-{
-       int len = strlen(name);
-       if (interpret_branch_name(name, sb) == len)
-               return 0;
-       strbuf_add(sb, name, len);
-       return len;
-}
-
-int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
-{
-       strbuf_branchname(sb, name);
-       strbuf_splice(sb, 0, 0, "refs/heads/", 11);
-       return check_ref_format(sb->buf);
-}