Commit 49938cad by Carlos Martín Nieto

config: correctly escape quotes in the value

When a configuration option is set, we didn't check to see whether
there was any escaping needed. Escape the available characters so we
can unescape them correctly when we read them.
parent 750be86a
...@@ -87,6 +87,7 @@ typedef struct { ...@@ -87,6 +87,7 @@ typedef struct {
static int config_parse(diskfile_backend *cfg_file); static int config_parse(diskfile_backend *cfg_file);
static int parse_variable(diskfile_backend *cfg, char **var_name, char **var_value); static int parse_variable(diskfile_backend *cfg, char **var_name, char **var_value);
static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value); static int config_write(diskfile_backend *cfg, const char *key, const regex_t *preg, const char *value);
static char *escape_value(const char *ptr);
static void set_parse_error(diskfile_backend *backend, int col, const char *error_str) static void set_parse_error(diskfile_backend *backend, int col, const char *error_str)
{ {
...@@ -212,9 +213,9 @@ static int config_set(git_config_file *cfg, const char *name, const char *value) ...@@ -212,9 +213,9 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
{ {
cvar_t *var = NULL, *old_var; cvar_t *var = NULL, *old_var;
diskfile_backend *b = (diskfile_backend *)cfg; diskfile_backend *b = (diskfile_backend *)cfg;
char *key; char *key, *esc_value = NULL;
khiter_t pos; khiter_t pos;
int rval; int rval, ret;
if (normalize_name(name, &key) < 0) if (normalize_name(name, &key) < 0)
return -1; return -1;
...@@ -237,12 +238,17 @@ static int config_set(git_config_file *cfg, const char *name, const char *value) ...@@ -237,12 +238,17 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
if (value) { if (value) {
tmp = git__strdup(value); tmp = git__strdup(value);
GITERR_CHECK_ALLOC(tmp); GITERR_CHECK_ALLOC(tmp);
esc_value = escape_value(value);
GITERR_CHECK_ALLOC(esc_value);
} }
git__free(existing->value); git__free(existing->value);
existing->value = tmp; existing->value = tmp;
return config_write(b, existing->key, NULL, value); ret = config_write(b, existing->key, NULL, esc_value);
git__free(esc_value);
return ret;
} }
var = git__malloc(sizeof(cvar_t)); var = git__malloc(sizeof(cvar_t));
...@@ -256,13 +262,17 @@ static int config_set(git_config_file *cfg, const char *name, const char *value) ...@@ -256,13 +262,17 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
if (value) { if (value) {
var->value = git__strdup(value); var->value = git__strdup(value);
GITERR_CHECK_ALLOC(var->value); GITERR_CHECK_ALLOC(var->value);
esc_value = escape_value(value);
GITERR_CHECK_ALLOC(esc_value);
} }
if (config_write(b, key, NULL, value) < 0) { if (config_write(b, key, NULL, esc_value) < 0) {
git__free(esc_value);
cvar_free(var); cvar_free(var);
return -1; return -1;
} }
git__free(esc_value);
git_strmap_insert2(b->values, key, var, old_var, rval); git_strmap_insert2(b->values, key, var, old_var, rval);
if (rval < 0) if (rval < 0)
return -1; return -1;
...@@ -1155,13 +1165,44 @@ rewrite_fail: ...@@ -1155,13 +1165,44 @@ rewrite_fail:
return -1; return -1;
} }
static const char *escapes = "ntb\"\\";
static const char *escaped = "\n\t\b\"\\";
/* Escape the values to write them to the file */
static char *escape_value(const char *ptr)
{
git_buf buf = GIT_BUF_INIT;
size_t len;
const char *esc;
assert(ptr);
len = strlen(ptr);
git_buf_grow(&buf, len);
while (*ptr != '\0') {
if ((esc = strchr(escaped, *ptr)) != NULL) {
git_buf_putc(&buf, '\\');
git_buf_putc(&buf, escapes[esc - escaped]);
} else {
git_buf_putc(&buf, *ptr);
}
ptr++;
}
if (git_buf_oom(&buf)) {
git_buf_free(&buf);
return NULL;
}
return git_buf_detach(&buf);
}
/* '\"' -> '"' etc */ /* '\"' -> '"' etc */
static char *fixup_line(const char *ptr, int quote_count) static char *fixup_line(const char *ptr, int quote_count)
{ {
char *str = git__malloc(strlen(ptr) + 1); char *str = git__malloc(strlen(ptr) + 1);
char *out = str, *esc; char *out = str, *esc;
const char *escapes = "ntb\"\\";
const char *escaped = "\n\t\b\"\\";
if (str == NULL) if (str == NULL)
return NULL; return NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment