Parse hexadecimal escapes in strings (from Lua 5.2).

This commit is contained in:
Mike Pall 2010-11-19 17:39:33 +01:00
parent 57cd5026eb
commit 29b8959df1
2 changed files with 29 additions and 13 deletions

View File

@ -117,7 +117,7 @@ ERRDEF(XNUMBER, "malformed number")
ERRDEF(XLSTR, "unfinished long string")
ERRDEF(XLCOM, "unfinished long comment")
ERRDEF(XSTR, "unfinished string")
ERRDEF(XESC, "escape sequence too large")
ERRDEF(XESC, "invalid escape sequence")
ERRDEF(XLDELIM, "invalid long string delimiter")
ERRDEF(XBCLOAD, "cannot load Lua bytecode")
ERRDEF(XTOKEN, LUA_QS " expected")

View File

@ -154,7 +154,7 @@ static void read_string(LexState *ls, int delim, TValue *tv)
continue;
case '\\': {
int c;
next(ls); /* do not save the `\' */
next(ls); /* Skip the '\\'. */
switch (ls->current) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
@ -163,20 +163,36 @@ static void read_string(LexState *ls, int delim, TValue *tv)
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case 'x': /* Hexadecimal escape '\xXX'. */
c = (next(ls) & 15u) << 4;
if (!lj_char_isdigit(ls->current)) {
if (!lj_char_isxdigit(ls->current)) goto err_xesc;
c += 9 << 4;
}
c += (next(ls) & 15u);
if (!lj_char_isdigit(ls->current)) {
if (!lj_char_isxdigit(ls->current)) goto err_xesc;
c += 9;
}
break;
case '\n': case '\r': save(ls, '\n'); inclinenumber(ls); continue;
case END_OF_STREAM: continue; /* will raise an error next loop */
case END_OF_STREAM: continue;
default:
if (!lj_char_isdigit(ls->current)) {
save_and_next(ls); /* handles \\, \", \', and \? */
} else { /* \xxx */
int i = 0;
c = 0;
do {
c = 10*c + (ls->current-'0');
next(ls);
} while (++i<3 && lj_char_isdigit(ls->current));
if (c > 255)
lj_lex_error(ls, TK_string, LJ_ERR_XESC);
save_and_next(ls); /* Handles '\\', '\"' and "\'". */
} else { /* Decimal escape '\ddd'. */
c = (ls->current - '0');
if (lj_char_isdigit(next(ls))) {
c = c*10 + (ls->current - '0');
if (lj_char_isdigit(next(ls))) {
c = c*10 + (ls->current - '0');
if (c > 255) {
err_xesc:
lj_lex_error(ls, TK_string, LJ_ERR_XESC);
}
next(ls);
}
}
save(ls, c);
}
continue;