ident: use a dynamic strbuf in fmt_ident

Now that we accept arbitrary-sized names and email addresses, the only remaining limit is in the actual formatting of the names into a buffer. The current limit is 1000 characters, which is not likely to be reached, but using a strbuf is one less error condition we have to worry about. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed May 21, 2012 at 19:10 UTC c96f0c8d0a9f1eeabb2ea49cb7ede954a64bd540
1 file changed +15 -28
ident.c
+15 -28
@@ -121,15 +121,6 @@ const char *ident_default_date(void)
121 return git_default_date;
122 }
123
124 -static int add_raw(char *buf, size_t size, int offset, const char *str)
125 -{
126 - size_t len = strlen(str);
127 - if (offset + len > size)
128 - return size;
129 - memcpy(buf + offset, str, len);
130 - return offset + len;
131 -}
132 -
124 static int crud(unsigned char c)
125 {
126 return c <= 32 ||
@@ -148,7 +139,7 @@ static int crud(unsigned char c)
139 * Copy over a string to the destination, but avoid special
140 * characters ('\n', '<' and '>') and remove crud at the end
141 */
151 -static int copy(char *buf, size_t size, int offset, const char *src)
142 +static void strbuf_addstr_without_crud(struct strbuf *sb, const char *src)
143 {
144 size_t i, len;
145 unsigned char c;
@@ -172,19 +163,19 @@ static int copy(char *buf, size_t size, int offset, const char *src)
163 /*
164 * Copy the rest to the buffer, but avoid the special
165 * characters '\n' '<' and '>' that act as delimiters on
175 - * an identification line
166 + * an identification line. We can only remove crud, never add it,
167 + * so 'len' is our maximum.
168 */
169 + strbuf_grow(sb, len);
170 for (i = 0; i < len; i++) {
171 c = *src++;
172 switch (c) {
173 case '\n': case '<': case '>':
174 continue;
175 }
183 - if (offset >= size)
184 - return size;
185 - buf[offset++] = c;
176 + sb->buf[sb->len++] = c;
177 }
187 - return offset;
178 + sb->buf[sb->len] = '\0';
179 }
180
181 /*
@@ -271,9 +262,8 @@ static const char *env_hint =
262 const char *fmt_ident(const char *name, const char *email,
263 const char *date_str, int flag)
264 {
274 - static char buffer[1000];
265 + static struct strbuf ident = STRBUF_INIT;
266 char date[50];
276 - int i;
267 int error_on_no_name = (flag & IDENT_ERROR_ON_NO_NAME);
268 int name_addr_only = (flag & IDENT_NO_DATE);
269
@@ -300,19 +290,16 @@ const char *fmt_ident(const char *name, const char *email,
290 die("invalid date format: %s", date_str);
291 }
292
303 - i = copy(buffer, sizeof(buffer), 0, name);
304 - i = add_raw(buffer, sizeof(buffer), i, " <");
305 - i = copy(buffer, sizeof(buffer), i, email);
293 + strbuf_reset(&ident);
294 + strbuf_addstr_without_crud(&ident, name);
295 + strbuf_addstr(&ident, " <");
296 + strbuf_addstr_without_crud(&ident, email);
297 + strbuf_addch(&ident, '>');
298 if (!name_addr_only) {
307 - i = add_raw(buffer, sizeof(buffer), i, "> ");
308 - i = copy(buffer, sizeof(buffer), i, date);
309 - } else {
310 - i = add_raw(buffer, sizeof(buffer), i, ">");
299 + strbuf_addch(&ident, ' ');
300 + strbuf_addstr_without_crud(&ident, date);
301 }
312 - if (i >= sizeof(buffer))
313 - die("Impossibly long personal identifier");
314 - buffer[i] = 0;
315 - return buffer;
302 + return ident.buf;
303 }
304
305 const char *fmt_name(const char *name, const char *email)