From d892bbfd0e53c860823f1bdf98e0a6a4172351d3 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 4 Apr 2018 23:00:49 -0700 Subject: regex: read/print bug: escaped double quote. Because the regex printer wrongly uses out_str_char (for the sake of borrowing its semicolon-notation processing) when a regex prints, all characters that require escaping in a string literal get escaped, which includes the " character. Unfortunately the \" sequence which results is rejected by the regex parser. * lib.c (out_str_char): Kludge: add extra argument to distinguish regex use versus string use, and treat the double quote accordingly. (out_str_readable): Give 0 arg to new param of out_str_char. * lib.h (out_str_char): Declaration updated. * regex.c (print_class_char, print_rec): Pass 1 to new param of out_str_char. --- lib.c | 11 ++++++++--- lib.h | 2 +- regex.c | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib.c b/lib.c index f089ee90..cf800c52 100644 --- a/lib.c +++ b/lib.c @@ -10849,7 +10849,7 @@ static val simple_qref_args_p(val args, val pos) } } -void out_str_char(wchar_t ch, val out, int *semi_flag) +void out_str_char(wchar_t ch, val out, int *semi_flag, int regex) { if (*semi_flag && (iswxdigit(ch) || ch == ';')) put_char(chr(';'), out); @@ -10864,9 +10864,14 @@ void out_str_char(wchar_t ch, val out, int *semi_flag) case '\v': put_string(lit("\\v"), out); break; case '\f': put_string(lit("\\f"), out); break; case '\r': put_string(lit("\\r"), out); break; - case '"': put_string(lit("\\\""), out); break; case '\\': put_string(lit("\\\\"), out); break; case 27: put_string(lit("\\e"), out); break; + case '"': + if (regex) + put_char(chr(ch), out); + else + put_string(lit("\\\""), out); + break; default: { val fmt = nil; @@ -10891,7 +10896,7 @@ void out_str_char(wchar_t ch, val out, int *semi_flag) static void out_str_readable(const wchar_t *ptr, val out, int *semi_flag) { for (; *ptr; ptr++) - out_str_char(*ptr, out, semi_flag); + out_str_char(*ptr, out, semi_flag, 0); } static void out_lazy_str(val lstr, val out) diff --git a/lib.h b/lib.h index 6fe29fe2..b473b4dd 100644 --- a/lib.h +++ b/lib.h @@ -1069,7 +1069,7 @@ val to(val range); val set_from(val range, val from); val set_to(val range, val to); val env(void); -void out_str_char(wchar_t ch, val out, int *semi_flag); +void out_str_char(wchar_t ch, val out, int *semi_flag, int regex); val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *); val obj_print(val obj, val stream, val pretty); val print(val obj, val stream, val pretty); diff --git a/regex.c b/regex.c index 47693e97..3fb6b42c 100644 --- a/regex.c +++ b/regex.c @@ -2272,7 +2272,7 @@ static void print_class_char(val ch, val first_p, val stream, int *semi_flag) put_char(ch, stream); return; } - out_str_char(c_chr(ch), stream, semi_flag); + out_str_char(c_chr(ch), stream, semi_flag, 1); } static void print_rec(val exp, val stream, int *semi_flag); @@ -2311,7 +2311,7 @@ static void print_rec(val exp, val stream, int *semi_flag) put_char(exp, stream); break; default: - out_str_char(ch, stream, semi_flag); + out_str_char(ch, stream, semi_flag, 1); } } else if (stringp(exp)) { cnum i; -- cgit v1.2.3