diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-26 11:15:51 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-26 11:15:51 -0300 |
| commit | 69b71a69197de0cb6f7f58f5d7c55d9a9a6e529d (patch) | |
| tree | 8323373db70b7feb06691634c5431c3d6bbe9f3e | |
| parent | d742a193e57029d973aff0a5eb04d8ddd03fa0ff (diff) | |
| download | lua-69b71a69197de0cb6f7f58f5d7c55d9a9a6e529d.tar.gz lua-69b71a69197de0cb6f7f58f5d7c55d9a9a6e529d.tar.bz2 lua-69b71a69197de0cb6f7f58f5d7c55d9a9a6e529d.zip | |
_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.
| -rw-r--r-- | lua.c | 16 | ||||
| -rw-r--r-- | testes/main.lua | 27 |
2 files changed, 37 insertions, 6 deletions
| @@ -416,14 +416,18 @@ static int handle_luainit (lua_State *L) { | |||
| 416 | 416 | ||
| 417 | 417 | ||
| 418 | /* | 418 | /* |
| 419 | ** Returns the string to be used as a prompt by the interpreter. | 419 | ** Return the string to be used as a prompt by the interpreter. Leave |
| 420 | ** the string (or nil, if using the default value) on the stack, to keep | ||
| 421 | ** it anchored. | ||
| 420 | */ | 422 | */ |
| 421 | static const char *get_prompt (lua_State *L, int firstline) { | 423 | static const char *get_prompt (lua_State *L, int firstline) { |
| 422 | const char *p; | 424 | if (lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2") == LUA_TNIL) |
| 423 | lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); | 425 | return (firstline ? LUA_PROMPT : LUA_PROMPT2); /* use the default */ |
| 424 | p = lua_tostring(L, -1); | 426 | else { /* apply 'tostring' over the value */ |
| 425 | if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); | 427 | const char *p = luaL_tolstring(L, -1, NULL); |
| 426 | return p; | 428 | lua_remove(L, -2); /* remove original value */ |
| 429 | return p; | ||
| 430 | } | ||
| 427 | } | 431 | } |
| 428 | 432 | ||
| 429 | /* mark in error messages for incomplete statements */ | 433 | /* 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) | |||
| 287 | local t = getoutput() | 287 | local t = getoutput() |
| 288 | assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)) | 288 | assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)) |
| 289 | 289 | ||
| 290 | -- using the prompt default | ||
| 291 | prepfile[[ -- | ||
| 292 | a = 2 | ||
| 293 | ]] | ||
| 294 | RUN([[lua -i < %s > %s]], prog, out) | ||
| 295 | local t = getoutput() | ||
| 296 | prompt = "> " -- the default | ||
| 297 | assert(string.find(t, prompt .. ".*" .. prompt .. ".*" .. prompt)) | ||
| 298 | |||
| 299 | |||
| 300 | -- non-string prompt | ||
| 301 | prompt = | ||
| 302 | "local C = 0;\z | ||
| 303 | _PROMPT=setmetatable({},{__tostring = function () \z | ||
| 304 | C = C + 1; return C end})" | ||
| 305 | prepfile[[ -- | ||
| 306 | a = 2 | ||
| 307 | ]] | ||
| 308 | RUN([[lua -e "%s" -i < %s > %s]], prompt, prog, out) | ||
| 309 | local t = getoutput() | ||
| 310 | assert(string.find(t, [[ | ||
| 311 | 1 -- | ||
| 312 | 2a = 2 | ||
| 313 | 3 | ||
| 314 | ]], 1, true)) | ||
| 315 | |||
| 316 | |||
| 290 | -- test for error objects | 317 | -- test for error objects |
| 291 | prepfile[[ | 318 | prepfile[[ |
| 292 | debug = require "debug" | 319 | debug = require "debug" |
