Skip to content

Commit

Permalink
* src/put.c (create_del): do not unescape the string before writing i…
Browse files Browse the repository at this point in the history
…t 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: hercules-team#507
  • Loading branch information
lutter committed Sep 29, 2017
1 parent e1a8608 commit a699288
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 45 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
47 changes: 2 additions & 45 deletions src/put.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
}
}

Expand Down
14 changes: 14 additions & 0 deletions tests/modules/pass_create_del.aug
Original file line number Diff line number Diff line change
@@ -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"

0 comments on commit a699288

Please sign in to comment.