aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-05 14:31:07 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-05 14:31:07 -0300
commit30982bec968fd34694b5be3ecbbc92de78d8eacb (patch)
tree9b2b350be7c79b7237e8ffbe84dc90c6c7cc5089
parent1ab3208a1fceb12fca8f24ba57d6e13c5bff15e3 (diff)
downloadlua-30982bec968fd34694b5be3ecbbc92de78d8eacb.tar.gz
lua-30982bec968fd34694b5be3ecbbc92de78d8eacb.tar.bz2
lua-30982bec968fd34694b5be3ecbbc92de78d8eacb.zip
Bug: Bad stack manipulation in 'multiline' (REPL)
'incomplete' was popping error message that should be used in case there is no more lines to complete the input, that is, 'pushline' returns NULL, due to end of file.
-rw-r--r--lua.c11
-rw-r--r--testes/main.lua5
2 files changed, 10 insertions, 6 deletions
diff --git a/lua.c b/lua.c
index 6da331f1..4a90e55d 100644
--- a/lua.c
+++ b/lua.c
@@ -490,10 +490,8 @@ static int incomplete (lua_State *L, int status) {
490 if (status == LUA_ERRSYNTAX) { 490 if (status == LUA_ERRSYNTAX) {
491 size_t lmsg; 491 size_t lmsg;
492 const char *msg = lua_tolstring(L, -1, &lmsg); 492 const char *msg = lua_tolstring(L, -1, &lmsg);
493 if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { 493 if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0)
494 lua_pop(L, 1);
495 return 1; 494 return 1;
496 }
497 } 495 }
498 return 0; /* else... */ 496 return 0; /* else... */
499} 497}
@@ -508,9 +506,9 @@ static int pushline (lua_State *L, int firstline) {
508 size_t l; 506 size_t l;
509 const char *prmt = get_prompt(L, firstline); 507 const char *prmt = get_prompt(L, firstline);
510 int readstatus = lua_readline(L, b, prmt); 508 int readstatus = lua_readline(L, b, prmt);
511 if (readstatus == 0)
512 return 0; /* no input (prompt will be popped by caller) */
513 lua_pop(L, 1); /* remove prompt */ 509 lua_pop(L, 1); /* remove prompt */
510 if (readstatus == 0)
511 return 0; /* no input */
514 l = strlen(b); 512 l = strlen(b);
515 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ 513 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
516 b[--l] = '\0'; /* remove it */ 514 b[--l] = '\0'; /* remove it */
@@ -552,8 +550,9 @@ static int multiline (lua_State *L) {
552 int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ 550 int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
553 if (!incomplete(L, status) || !pushline(L, 0)) { 551 if (!incomplete(L, status) || !pushline(L, 0)) {
554 lua_saveline(L, line); /* keep history */ 552 lua_saveline(L, line); /* keep history */
555 return status; /* cannot or should not try to add continuation line */ 553 return status; /* should not or cannot try to add continuation line */
556 } 554 }
555 lua_remove(L, -2); /* remove error message (from incomplete line) */
557 lua_pushliteral(L, "\n"); /* add newline... */ 556 lua_pushliteral(L, "\n"); /* add newline... */
558 lua_insert(L, -2); /* ...between the two lines */ 557 lua_insert(L, -2); /* ...between the two lines */
559 lua_concat(L, 3); /* join them */ 558 lua_concat(L, 3); /* join them */
diff --git a/testes/main.lua b/testes/main.lua
index 11b14b44..cec4fa04 100644
--- a/testes/main.lua
+++ b/testes/main.lua
@@ -349,6 +349,11 @@ prepfile("a = [[b\nc\nd\ne]]\n=a")
349RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out) 349RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
350checkprogout("b\nc\nd\ne\n\n") 350checkprogout("b\nc\nd\ne\n\n")
351 351
352-- input interrupted in continuation line
353prepfile("a.\n")
354RUN([[lua -i < %s > /dev/null 2> %s]], prog, out)
355checkprogout("near <eof>\n")
356
352local prompt = "alo" 357local prompt = "alo"
353prepfile[[ -- 358prepfile[[ --
354a = 2 359a = 2