| @@ -1,5 +1,5 @@ |
| 1 | 1 | /* |
| 2 | | −** $Id: llex.c,v 2.50 2011/07/05 19:13:45 roberto Exp $ |
| 2 | +** $Id: llex.c,v 2.53 2011/07/08 20:01:38 roberto Exp $ |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -286,45 +286,51 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { · 280 unmodified lines |
| 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 | 299 | static int readhexaesc (LexState *ls) { |
| 290 | | − int c1 = next(ls); |
| 291 | | − int c2 = EOZ; |
| 292 | | − if (lisxdigit(c1)) { |
| 293 | | − c2 = next(ls); |
| 294 | | − if (lisxdigit(c2)) |
| 295 | | − return (luaO_hexavalue(c1) << 4) + luaO_hexavalue(c2); |
| 300 | + int c[3]; /* keep input for error message */ |
| 301 | + int i = 2; /* at least 'x?' will go to error message */ |
| 302 | + c[0] = 'x'; |
| 303 | + c[1] = next(ls); /* first hexa digit */ |
| 304 | + if (lisxdigit(c[1])) { |
| 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 | 308 | /* else go through to error */ |
| 297 | 309 | } |
| 298 | | − luaZ_resetbuffer(ls->buff); /* prepare error message */ |
| 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); |
| 310 | + escerror(ls, c, i, "hexadecimal digit expected"); |
| 303 | 311 | return 0; /* to avoid warnings */ |
| 304 | 312 | } |
| 305 | 313 | |
| 306 | 314 | |
| 307 | 315 | static int readdecesc (LexState *ls) { |
| 308 | | − int c1 = ls->current; /* first char must be a digit */ |
| 309 | | − int c2 = next(ls); /* read second char */ |
| 310 | | − int c = c1 - '0'; /* partial result */ |
| 311 | | − if (lisdigit(c2)) { |
| 312 | | − int c3 = next(ls); /* read third char */ |
| 313 | | − c = 10*c + c2 - '0'; /* update result */ |
| 314 | | − if (lisdigit(c3)) { |
| 315 | | − c = 10*c + c3 - '0'; /* update result */ |
| 316 | | − if (c > UCHAR_MAX) { |
| 317 | | − luaZ_resetbuffer(ls->buff); /* prepare error message */ |
| 318 | | − save(ls, '\\'); |
| 319 | | − save(ls, c1); save(ls, c2); save(ls, c3); |
| 320 | | − lexerror(ls, "decimal escape too large", TK_STRING); |
| 321 | | − } |
| 322 | | − return c; |
| 316 | + int c[3], r; |
| 317 | + int i = 2; /* at least two chars will be read */ |
| 318 | + c[0] = ls->current; /* first char must be a digit */ |
| 319 | + c[1] = next(ls); /* read second char */ |
| 320 | + r = c[0] - '0'; /* partial result */ |
| 321 | + if (lisdigit(c[1])) { |
| 322 | + c[i++] = next(ls); /* read third char */ |
| 323 | + r = 10*r + c[1] - '0'; /* update result */ |
| 324 | + if (lisdigit(c[2])) { |
| 325 | + r = 10*r + c[2] - '0'; /* update result */ |
| 326 | + if (r > UCHAR_MAX) |
| 327 | + escerror(ls, c, i, "decimal escape too large"); |
| 328 | + return r; |
| 323 | 329 | } |
| 324 | 330 | } |
| 325 | 331 | /* else, has read one character that was not a digit */ |
| 326 | 332 | zungetc(ls->z); /* return it to input stream */ |
| 327 | | − return c; |
| 333 | + return r; |
| 328 | 334 | } |
| 329 | 335 | |
| 330 | 336 | |
| @@ -353,9 +359,10 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 22 unmodified lines |
| 353 | 359 | case 'x': c = readhexaesc(ls); break; |
| 354 | 360 | case '\n': |
| 355 | 361 | case '\r': save(ls, '\n'); inclinenumber(ls); continue; |
| 362 | + case '\\': case '\"': case '\'': c = ls->current; break; |
| 356 | 363 | case EOZ: continue; /* will raise an error next loop */ |
| 357 | 364 | case 'z': { /* zap following span of spaces */ |
| 358 | | − next(ls); /* skip the '*' */ |
| 365 | + next(ls); /* skip the 'z' */ |
| 359 | 366 | while (lisspace(ls->current)) { |
| 360 | 367 | if (currIsNewline(ls)) inclinenumber(ls); |
| 361 | 368 | else next(ls); |
| @@ -364,9 +371,9 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 2 unmodified lines |
| 364 | 371 | } |
| 365 | 372 | default: { |
| 366 | 373 | if (!lisdigit(ls->current)) |
| 367 | | − c = ls->current; /* handles \\, \", and \' */ |
| 368 | | − else /* digital escape \ddd */ |
| 369 | | − c = readdecesc(ls); |
| 374 | + escerror(ls, &ls->current, 1, "invalid escape sequence"); |
| 375 | + /* digital escape \ddd */ |
| 376 | + c = readdecesc(ls); |
| 370 | 377 | break; |
| 371 | 378 | } |
| 372 | 379 | } |