From a699288d9176e6376cf530062b30a8e65488cce0 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Thu, 28 Sep 2017 16:49:19 -0700 Subject: [PATCH] * src/put.c (create_del): do not unescape the string before writing it out We already unescape the default for a del when we read the lens file. Doing it during put will cause two rounds of unescaping to happen, which is wrong. Fixes: https://github.com/hercules-team/augeas/issues/507 --- NEWS | 2 ++ src/put.c | 47 ++----------------------------- tests/modules/pass_create_del.aug | 14 +++++++++ 3 files changed, 18 insertions(+), 45 deletions(-) create mode 100644 tests/modules/pass_create_del.aug diff --git a/NEWS b/NEWS index b0804909e..4bf26129d 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ quickly. See examples/dump.c for an example of how to use them instead of aug_get, aug_label etc. and for a way to measure performance gains. + * do not unescape the default value of a del on create; otherwise we are + double unescaping these strings (Issue #507) - Lens changes/additions * Exports: relax the rules for the path at the beginning of a line so that double-quoted paths are legal, too diff --git a/src/put.c b/src/put.c index 5bc951448..8d3ec9279 100644 --- a/src/put.c +++ b/src/put.c @@ -312,49 +312,6 @@ static int applies(struct lens *lens, struct state *state) { return 1; } -/* Print TEXT to OUT, translating common escapes like \n */ -static void print_escaped_chars(FILE *out, const char *text) { - for (const char *c = text; *c != '\0'; c++) { - if (*c == '\\') { - char x; - c += 1; - if (*c == '\0') { - fputc(*c, out); - break; - } - switch(*c) { - case 'a': - x = '\a'; - break; - case 'b': - x = '\b'; - break; - case 'f': - x = '\f'; - break; - case 'n': - x = '\n'; - break; - case 'r': - x = '\r'; - break; - case 't': - x = '\t'; - break; - case 'v': - x = '\v'; - break; - default: - x = *c; - break; - } - fputc(x, out); - } else { - fputc(*c, out); - } - } -} - /* * Check whether SKEL has the skeleton type required by LENS */ @@ -735,9 +692,9 @@ static void create_subtree(struct lens *lens, struct state *state) { static void create_del(struct lens *lens, struct state *state) { assert(lens->tag == L_DEL); if (state->override != NULL) { - print_escaped_chars(state->out, state->override); + emit(state, state->override, S_NONE); } else { - print_escaped_chars(state->out, lens->string->str); + emit(state, lens->string->str, S_NONE); } } diff --git a/tests/modules/pass_create_del.aug b/tests/modules/pass_create_del.aug new file mode 100644 index 000000000..7aec6f48d --- /dev/null +++ b/tests/modules/pass_create_del.aug @@ -0,0 +1,14 @@ +module Pass_Create_Del = + +(* del, on create, would do another round of unescaping the default value + * which is wrong. See Issue #507 *) +let sep = del /:([ \t]*\\\\\n[ \t]*:)?/ ":\\\n\t:" + +let lns = [ label "entry" . sep . store /[a-z]+/ ]* + +test lns get ":a:\\\n:b" = + { "entry" = "a" } + { "entry" = "b" } + +test lns put ":a" after + set "/entry[last()+1]" "b" = ":a:\\\n\t:b"