Skip to content

Commit 6a83a6d

Browse files
committed
Merge branch 'bw/config-lift-variable-name-length-limit'
The configuration parser had an unnecessary hardcoded limit on variable names that was not checked consistently. Lift the limit. * bw/config-lift-variable-name-length-limit: Remove the hard coded length limit on variable names in config files
2 parents 530f237 + 0971e99 commit 6a83a6d

File tree

1 file changed

+29
-30
lines changed

1 file changed

+29
-30
lines changed

config.c

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,14 @@
1010
#include "strbuf.h"
1111
#include "quote.h"
1212

13-
#define MAXNAME (256)
14-
1513
typedef struct config_file {
1614
struct config_file *prev;
1715
FILE *f;
1816
const char *name;
1917
int linenr;
2018
int eof;
2119
struct strbuf value;
22-
char var[MAXNAME];
20+
struct strbuf var;
2321
} config_file;
2422

2523
static config_file *cf;
@@ -260,7 +258,7 @@ static inline int iskeychar(int c)
260258
return isalnum(c) || c == '-';
261259
}
262260

263-
static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
261+
static int get_value(config_fn_t fn, void *data, struct strbuf *name)
264262
{
265263
int c;
266264
char *value;
@@ -272,11 +270,9 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
272270
break;
273271
if (!iskeychar(c))
274272
break;
275-
name[len++] = tolower(c);
276-
if (len >= MAXNAME)
277-
return -1;
273+
strbuf_addch(name, tolower(c));
278274
}
279-
name[len] = 0;
275+
280276
while (c == ' ' || c == '\t')
281277
c = get_next_char();
282278

@@ -288,10 +284,10 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
288284
if (!value)
289285
return -1;
290286
}
291-
return fn(name, value, data);
287+
return fn(name->buf, value, data);
292288
}
293289

294-
static int get_extended_base_var(char *name, int baselen, int c)
290+
static int get_extended_base_var(struct strbuf *name, int c)
295291
{
296292
do {
297293
if (c == '\n')
@@ -302,7 +298,7 @@ static int get_extended_base_var(char *name, int baselen, int c)
302298
/* We require the format to be '[base "extension"]' */
303299
if (c != '"')
304300
return -1;
305-
name[baselen++] = '.';
301+
strbuf_addch(name, '.');
306302

307303
for (;;) {
308304
int c = get_next_char();
@@ -315,45 +311,39 @@ static int get_extended_base_var(char *name, int baselen, int c)
315311
if (c == '\n')
316312
goto error_incomplete_line;
317313
}
318-
name[baselen++] = c;
319-
if (baselen > MAXNAME / 2)
320-
return -1;
314+
strbuf_addch(name, c);
321315
}
322316

323317
/* Final ']' */
324318
if (get_next_char() != ']')
325319
return -1;
326-
return baselen;
320+
return 0;
327321
error_incomplete_line:
328322
cf->linenr--;
329323
return -1;
330324
}
331325

332-
static int get_base_var(char *name)
326+
static int get_base_var(struct strbuf *name)
333327
{
334-
int baselen = 0;
335-
336328
for (;;) {
337329
int c = get_next_char();
338330
if (cf->eof)
339331
return -1;
340332
if (c == ']')
341-
return baselen;
333+
return 0;
342334
if (isspace(c))
343-
return get_extended_base_var(name, baselen, c);
335+
return get_extended_base_var(name, c);
344336
if (!iskeychar(c) && c != '.')
345337
return -1;
346-
if (baselen > MAXNAME / 2)
347-
return -1;
348-
name[baselen++] = tolower(c);
338+
strbuf_addch(name, tolower(c));
349339
}
350340
}
351341

352342
static int git_parse_file(config_fn_t fn, void *data)
353343
{
354344
int comment = 0;
355345
int baselen = 0;
356-
char *var = cf->var;
346+
struct strbuf *var = &cf->var;
357347

358348
/* U+FEFF Byte Order Mark in UTF8 */
359349
static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
@@ -389,17 +379,24 @@ static int git_parse_file(config_fn_t fn, void *data)
389379
continue;
390380
}
391381
if (c == '[') {
392-
baselen = get_base_var(var);
393-
if (baselen <= 0)
382+
/* Reset prior to determining a new stem */
383+
strbuf_reset(var);
384+
if (get_base_var(var) < 0 || var->len < 1)
394385
break;
395-
var[baselen++] = '.';
396-
var[baselen] = 0;
386+
strbuf_addch(var, '.');
387+
baselen = var->len;
397388
continue;
398389
}
399390
if (!isalpha(c))
400391
break;
401-
var[baselen] = tolower(c);
402-
if (get_value(fn, data, var, baselen+1) < 0)
392+
/*
393+
* Truncate the var name back to the section header
394+
* stem prior to grabbing the suffix part of the name
395+
* and the value.
396+
*/
397+
strbuf_setlen(var, baselen);
398+
strbuf_addch(var, tolower(c));
399+
if (get_value(fn, data, var) < 0)
403400
break;
404401
}
405402
die("bad config file line %d in %s", cf->linenr, cf->name);
@@ -899,12 +896,14 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
899896
top.linenr = 1;
900897
top.eof = 0;
901898
strbuf_init(&top.value, 1024);
899+
strbuf_init(&top.var, 1024);
902900
cf = &top;
903901

904902
ret = git_parse_file(fn, data);
905903

906904
/* pop config-file parsing state stack */
907905
strbuf_release(&top.value);
906+
strbuf_release(&top.var);
908907
cf = top.prev;
909908

910909
fclose(f);

0 commit comments

Comments
 (0)