summaryrefslogtreecommitdiff
path: root/llex.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-07-08 16:17:30 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2011-07-08 16:17:30 -0300
commitdf19931ddc949e25869092ee00c0091ee7d7643e (patch)
treec0904dacca7d2dc3f59392bf74ffbe05ea739cc5 /llex.c
parentb5084fdafe972470a12454e11485a7dece9b2da8 (diff)
downloadlua-df19931ddc949e25869092ee00c0091ee7d7643e.tar.gz
lua-df19931ddc949e25869092ee00c0091ee7d7643e.tar.bz2
lua-df19931ddc949e25869092ee00c0091ee7d7643e.zip
error on invalid escape sequences
Diffstat (limited to 'llex.c')
-rw-r--r--llex.c69
1 files 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 @@
1/* 1/*
2** $Id: llex.c,v 2.50 2011/07/05 19:13:45 roberto Exp roberto $ 2** $Id: llex.c,v 2.51 2011/07/06 16:45:14 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -286,45 +286,51 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
286} 286}
287 287
288 288
289static void escerror (LexState *ls, int *c, int n, const char *msg) {
290 int i;
291 luaZ_resetbuffer(ls->buff); /* prepare error message */
292 save(ls, '\\');
293 for (i = 0; i < n && c[i] != EOZ; i++)
294 save(ls, c[i]);
295 lexerror(ls, msg, TK_STRING);
296}
297
298
289static int readhexaesc (LexState *ls) { 299static int readhexaesc (LexState *ls) {
290 int c1 = next(ls); 300 int c[3]; /* keep input for error message */
291 int c2 = EOZ; 301 int i = 2; /* at least 'x?' will go to error message */
292 if (lisxdigit(c1)) { 302 c[0] = 'x';
293 c2 = next(ls); 303 c[1] = next(ls); /* first hexa digit */
294 if (lisxdigit(c2)) 304 if (lisxdigit(c[1])) {
295 return (luaO_hexavalue(c1) << 4) + luaO_hexavalue(c2); 305 c[i++] = next(ls); /* second hexa digit */
306 if (lisxdigit(c[2]))
307 return (luaO_hexavalue(c[1]) << 4) + luaO_hexavalue(c[2]);
296 /* else go through to error */ 308 /* else go through to error */
297 } 309 }
298 luaZ_resetbuffer(ls->buff); /* prepare error message */ 310 escerror(ls, c, i, "hexadecimal digit expected");
299 save(ls, '\\'); save(ls, 'x');
300 if (c1 != EOZ) save(ls, c1);
301 if (c2 != EOZ) save(ls, c2);
302 lexerror(ls, "hexadecimal digit expected", TK_STRING);
303 return 0; /* to avoid warnings */ 311 return 0; /* to avoid warnings */
304} 312}
305 313
306 314
307static int readdecesc (LexState *ls) { 315static int readdecesc (LexState *ls) {
308 int c1 = ls->current; /* first char must be a digit */ 316 int c[3], r;
309 int c2 = next(ls); /* read second char */ 317 int i = 0;
310 int c = c1 - '0'; /* partial result */ 318 c[i++] = ls->current; /* first char must be a digit */
311 if (lisdigit(c2)) { 319 c[i++] = next(ls); /* read second char */
312 int c3 = next(ls); /* read third char */ 320 r = c[0] - '0'; /* partial result */
313 c = 10*c + c2 - '0'; /* update result */ 321 if (lisdigit(c[1])) {
314 if (lisdigit(c3)) { 322 c[i++] = next(ls); /* read third char */
315 c = 10*c + c3 - '0'; /* update result */ 323 r = 10*r + c[1] - '0'; /* update result */
316 if (c > UCHAR_MAX) { 324 if (lisdigit(c[2])) {
317 luaZ_resetbuffer(ls->buff); /* prepare error message */ 325 r = 10*r + c[2] - '0'; /* update result */
318 save(ls, '\\'); 326 if (r > UCHAR_MAX)
319 save(ls, c1); save(ls, c2); save(ls, c3); 327 escerror(ls, c, i, "decimal escape too large");
320 lexerror(ls, "decimal escape too large", TK_STRING); 328 return r;
321 }
322 return c;
323 } 329 }
324 } 330 }
325 /* else, has read one character that was not a digit */ 331 /* else, has read one character that was not a digit */
326 zungetc(ls->z); /* return it to input stream */ 332 zungetc(ls->z); /* return it to input stream */
327 return c; 333 return r;
328} 334}
329 335
330 336
@@ -353,6 +359,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
353 case 'x': c = readhexaesc(ls); break; 359 case 'x': c = readhexaesc(ls); break;
354 case '\n': 360 case '\n':
355 case '\r': save(ls, '\n'); inclinenumber(ls); continue; 361 case '\r': save(ls, '\n'); inclinenumber(ls); continue;
362 case '\\': case '\"': case '\'': c = ls->current; break;
356 case EOZ: continue; /* will raise an error next loop */ 363 case EOZ: continue; /* will raise an error next loop */
357 case 'z': { /* zap following span of spaces */ 364 case 'z': { /* zap following span of spaces */
358 next(ls); /* skip the 'z' */ 365 next(ls); /* skip the 'z' */
@@ -364,9 +371,9 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) {
364 } 371 }
365 default: { 372 default: {
366 if (!lisdigit(ls->current)) 373 if (!lisdigit(ls->current))
367 c = ls->current; /* handles \\, \", and \' */ 374 escerror(ls, &ls->current, 1, "invalid escape sequence");
368 else /* digital escape \ddd */ 375 /* digital escape \ddd */
369 c = readdecesc(ls); 376 c = readdecesc(ls);
370 break; 377 break;
371 } 378 }
372 } 379 }