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)