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:
commit
d6ecf5638d
1 changed files with 29 additions and 30 deletions
59
config.c
59
config.c
|
@ -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 = ⊤
|
cf = ⊤
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue