diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-07-08 16:17:30 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-07-08 16:17:30 -0300 |
commit | df19931ddc949e25869092ee00c0091ee7d7643e (patch) | |
tree | c0904dacca7d2dc3f59392bf74ffbe05ea739cc5 /llex.c | |
parent | b5084fdafe972470a12454e11485a7dece9b2da8 (diff) | |
download | lua-df19931ddc949e25869092ee00c0091ee7d7643e.tar.gz lua-df19931ddc949e25869092ee00c0091ee7d7643e.tar.bz2 lua-df19931ddc949e25869092ee00c0091ee7d7643e.zip |
error on invalid escape sequences
Diffstat (limited to 'llex.c')
-rw-r--r-- | llex.c | 69 |
1 files changed, 38 insertions, 31 deletions
@@ -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 | ||
289 | static 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 | |||
289 | static int readhexaesc (LexState *ls) { | 299 | static 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 | ||
307 | static int readdecesc (LexState *ls) { | 315 | static 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 | } |