From df19931ddc949e25869092ee00c0091ee7d7643e Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 8 Jul 2011 16:17:30 -0300 Subject: [PATCH] error on invalid escape sequences --- llex.c | 69 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/llex.c b/llex.c index 5bd31d80..046eb2df 100644 --- a/llex.c +++ b/llex.c @@ -1,5 +1,5 @@ /* -** $Id: llex.c,v 2.50 2011/07/05 19:13:45 roberto Exp roberto $ +** $Id: llex.c,v 2.51 2011/07/06 16:45:14 roberto Exp roberto $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -286,45 +286,51 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { } +static void escerror (LexState *ls, int *c, int n, const char *msg) { + int i; + luaZ_resetbuffer(ls->buff); /* prepare error message */ + save(ls, '\\'); + for (i = 0; i < n && c[i] != EOZ; i++) + save(ls, c[i]); + lexerror(ls, msg, TK_STRING); +} + + static int readhexaesc (LexState *ls) { - int c1 = next(ls); - int c2 = EOZ; - if (lisxdigit(c1)) { - c2 = next(ls); - if (lisxdigit(c2)) - return (luaO_hexavalue(c1) << 4) + luaO_hexavalue(c2); + int c[3]; /* keep input for error message */ + int i = 2; /* at least 'x?' will go to error message */ + c[0] = 'x'; + c[1] = next(ls); /* first hexa digit */ + if (lisxdigit(c[1])) { + c[i++] = next(ls); /* second hexa digit */ + if (lisxdigit(c[2])) + return (luaO_hexavalue(c[1]) << 4) + luaO_hexavalue(c[2]); /* else go through to error */ } - luaZ_resetbuffer(ls->buff); /* prepare error message */ - save(ls, '\\'); save(ls, 'x'); - if (c1 != EOZ) save(ls, c1); - if (c2 != EOZ) save(ls, c2); - lexerror(ls, "hexadecimal digit expected", TK_STRING); + escerror(ls, c, i, "hexadecimal digit expected"); return 0; /* to avoid warnings */ } static int readdecesc (LexState *ls) { - int c1 = ls->current; /* first char must be a digit */ - int c2 = next(ls); /* read second char */ - int c = c1 - '0'; /* partial result */ - if (lisdigit(c2)) { - int c3 = next(ls); /* read third char */ - c = 10*c + c2 - '0'; /* update result */ - if (lisdigit(c3)) { - c = 10*c + c3 - '0'; /* update result */ - if (c > UCHAR_MAX) { - luaZ_resetbuffer(ls->buff); /* prepare error message */ - save(ls, '\\'); - save(ls, c1); save(ls, c2); save(ls, c3); - lexerror(ls, "decimal escape too large", TK_STRING); - } - return c; + int c[3], r; + int i = 0; + c[i++] = ls->current; /* first char must be a digit */ + c[i++] = next(ls); /* read second char */ + r = c[0] - '0'; /* partial result */ + if (lisdigit(c[1])) { + c[i++] = next(ls); /* read third char */ + r = 10*r + c[1] - '0'; /* update result */ + if (lisdigit(c[2])) { + r = 10*r + c[2] - '0'; /* update result */ + if (r > UCHAR_MAX) + escerror(ls, c, i, "decimal escape too large"); + return r; } } /* else, has read one character that was not a digit */ zungetc(ls->z); /* return it to input stream */ - return c; + return r; } @@ -353,6 +359,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { case 'x': c = readhexaesc(ls); break; case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue; + case '\\': case '\"': case '\'': c = ls->current; break; case EOZ: continue; /* will raise an error next loop */ case 'z': { /* zap following span of spaces */ next(ls); /* skip the 'z' */ @@ -364,9 +371,9 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { } default: { if (!lisdigit(ls->current)) - c = ls->current; /* handles \\, \", and \' */ - else /* digital escape \ddd */ - c = readdecesc(ls); + escerror(ls, &ls->current, 1, "invalid escape sequence"); + /* digital escape \ddd */ + c = readdecesc(ls); break; } }