From 69b71a69197de0cb6f7f58f5d7c55d9a9a6e529d Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 26 Oct 2020 11:15:51 -0300 Subject: [PATCH] _PROMPT can have non-string values 'get_prompt' uses 'luaL_tolstring' to convert _PROMPT or _PROMPT2 value to a string. That conversion may invoke a '__tostring' metamethod. --- lua.c | 16 ++++++++++------ testes/main.lua | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lua.c b/lua.c index 454ce12f..b5b884b6 100644 --- a/lua.c +++ b/lua.c @@ -416,14 +416,18 @@ static int handle_luainit (lua_State *L) { /* -** Returns the string to be used as a prompt by the interpreter. +** Return the string to be used as a prompt by the interpreter. Leave +** the string (or nil, if using the default value) on the stack, to keep +** it anchored. */ static const char *get_prompt (lua_State *L, int firstline) { - const char *p; - lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); - p = lua_tostring(L, -1); - if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); - return p; + if (lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2") == LUA_TNIL) + return (firstline ? LUA_PROMPT : LUA_PROMPT2); /* use the default */ + else { /* apply 'tostring' over the value */ + const char *p = luaL_tolstring(L, -1, NULL); + lua_remove(L, -2); /* remove original value */ + return p; + } } /* mark in error messages for incomplete statements */ diff --git a/testes/main.lua b/testes/main.lua index d2d602de..56959abd 100644 --- a/testes/main.lua +++ b/testes/main.lua @@ -287,6 +287,33 @@ RUN([[lua "-e_PROMPT='%s'" -i < %s > %s]], prompt, prog, out) local t = getoutput() assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)) +-- using the prompt default +prepfile[[ -- +a = 2 +]] +RUN([[lua -i < %s > %s]], prog, out) +local t = getoutput() +prompt = "> " -- the default +assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)) + + +-- non-string prompt +prompt = + "local C = 0;\z + _PROMPT=setmetatable({},{__tostring = function () \z + C = C + 1; return C end})" +prepfile[[ -- +a = 2 +]] +RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out) +local t = getoutput() +assert(string.find(t, [[ +1 -- +2a = 2 +3 +]], 1, true)) + + -- test for error objects prepfile[[ debug = require "debug"