1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-11-01 06:47:52 +01:00

Merge branch 'bw/config-lift-variable-name-length-limit' into maint

The configuration parser had an unnecessary hardcoded limit on
variable names that was not checked consistently.

* bw/config-lift-variable-name-length-limit:
  Remove the hard coded length limit on variable names in config files
This commit is contained in:
Junio C Hamano 2012-11-18 19:29:44 -08:00
commit d6ecf5638d

View file

@ -10,8 +10,6 @@
#include "strbuf.h" #include "strbuf.h"
#include "quote.h" #include "quote.h"
#define MAXNAME (256)
typedef struct config_file { typedef struct config_file {
struct config_file *prev; struct config_file *prev;
FILE *f; FILE *f;
@ -19,7 +17,7 @@ typedef struct config_file {
int linenr; int linenr;
int eof; int eof;
struct strbuf value; struct strbuf value;
char var[MAXNAME]; struct strbuf var;
} config_file; } config_file;
static config_file *cf; static config_file *cf;
@ -260,7 +258,7 @@ static inline int iskeychar(int c)
return isalnum(c) || c == '-'; return isalnum(c) || c == '-';
} }
static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) static int get_value(config_fn_t fn, void *data, struct strbuf *name)
{ {
int c; int c;
char *value; char *value;
@ -272,11 +270,9 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
break; break;
if (!iskeychar(c)) if (!iskeychar(c))
break; break;
name[len++] = tolower(c); strbuf_addch(name, tolower(c));
if (len >= MAXNAME)
return -1;
} }
name[len] = 0;
while (c == ' ' || c == '\t') while (c == ' ' || c == '\t')
c = get_next_char(); c = get_next_char();
@ -288,10 +284,10 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
if (!value) if (!value)
return -1; return -1;
} }
return fn(name, value, data); return fn(name->buf, value, data);
} }
static int get_extended_base_var(char *name, int baselen, int c) static int get_extended_base_var(struct strbuf *name, int c)
{ {
do { do {
if (c == '\n') if (c == '\n')
@ -302,7 +298,7 @@ static int get_extended_base_var(char *name, int baselen, int c)
/* We require the format to be '[base "extension"]' */ /* We require the format to be '[base "extension"]' */
if (c != '"') if (c != '"')
return -1; return -1;
name[baselen++] = '.'; strbuf_addch(name, '.');
for (;;) { for (;;) {
int c = get_next_char(); int c = get_next_char();
@ -315,37 +311,31 @@ static int get_extended_base_var(char *name, int baselen, int c)
if (c == '\n') if (c == '\n')
goto error_incomplete_line; goto error_incomplete_line;
} }
name[baselen++] = c; strbuf_addch(name, c);
if (baselen > MAXNAME / 2)
return -1;
} }
/* Final ']' */ /* Final ']' */
if (get_next_char() != ']') if (get_next_char() != ']')
return -1; return -1;
return baselen; return 0;
error_incomplete_line: error_incomplete_line:
cf->linenr--; cf->linenr--;
return -1; return -1;
} }
static int get_base_var(char *name) static int get_base_var(struct strbuf *name)
{ {
int baselen = 0;
for (;;) { for (;;) {
int c = get_next_char(); int c = get_next_char();
if (cf->eof) if (cf->eof)
return -1; return -1;
if (c == ']') if (c == ']')
return baselen; return 0;
if (isspace(c)) if (isspace(c))
return get_extended_base_var(name, baselen, c); return get_extended_base_var(name, c);
if (!iskeychar(c) && c != '.') if (!iskeychar(c) && c != '.')
return -1; return -1;
if (baselen > MAXNAME / 2) strbuf_addch(name, tolower(c));
return -1;
name[baselen++] = tolower(c);
} }
} }
@ -353,7 +343,7 @@ static int git_parse_file(config_fn_t fn, void *data)
{ {
int comment = 0; int comment = 0;
int baselen = 0; int baselen = 0;
char *var = cf->var; struct strbuf *var = &cf->var;
/* U+FEFF Byte Order Mark in UTF8 */ /* U+FEFF Byte Order Mark in UTF8 */
static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf"; 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)
continue; continue;
} }
if (c == '[') { if (c == '[') {
baselen = get_base_var(var); /* Reset prior to determining a new stem */
if (baselen <= 0) strbuf_reset(var);
if (get_base_var(var) < 0 || var->len < 1)
break; break;
var[baselen++] = '.'; strbuf_addch(var, '.');
var[baselen] = 0; baselen = var->len;
continue; continue;
} }
if (!isalpha(c)) if (!isalpha(c))
break; break;
var[baselen] = tolower(c); /*
if (get_value(fn, data, var, baselen+1) < 0) * Truncate the var name back to the section header
* stem prior to grabbing the suffix part of the name
* and the value.
*/
strbuf_setlen(var, baselen);
strbuf_addch(var, tolower(c));
if (get_value(fn, data, var) < 0)
break; break;
} }
die("bad config file line %d in %s", cf->linenr, cf->name); 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)
top.linenr = 1; top.linenr = 1;
top.eof = 0; top.eof = 0;
strbuf_init(&top.value, 1024); strbuf_init(&top.value, 1024);
strbuf_init(&top.var, 1024);
cf = &top; cf = &top;
ret = git_parse_file(fn, data); ret = git_parse_file(fn, data);
/* pop config-file parsing state stack */ /* pop config-file parsing state stack */
strbuf_release(&top.value); strbuf_release(&top.value);
strbuf_release(&top.var);
cf = top.prev; cf = top.prev;
fclose(f); fclose(f);