diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2025-10-10 13:22:19 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2025-10-10 13:22:19 -0300 |
| commit | 3347c9d32d4d91b6139bff475c78cf0c4796e2a7 (patch) | |
| tree | 008f1f82a5481149ce07328a188b72b535409f84 | |
| parent | 25c54fe60e22d05cdfaa48c64372d354efa59547 (diff) | |
| download | lua-3347c9d32d4d91b6139bff475c78cf0c4796e2a7.tar.gz lua-3347c9d32d4d91b6139bff475c78cf0c4796e2a7.tar.bz2 lua-3347c9d32d4d91b6139bff475c78cf0c4796e2a7.zip | |
Initialization of too many locals break assertion
The check for limit of local variables is made after generating code to
initialize them. If there are too many local variables not initialized,
the coding of instruction OP_LOADNIL could overflow an argument.
Diffstat (limited to '')
| -rw-r--r-- | lparser.c | 1 | ||||
| -rw-r--r-- | testes/errors.lua | 19 |
2 files changed, 13 insertions, 7 deletions
| @@ -547,6 +547,7 @@ static void singlevar (LexState *ls, expdesc *var) { | |||
| 547 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | 547 | static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { |
| 548 | FuncState *fs = ls->fs; | 548 | FuncState *fs = ls->fs; |
| 549 | int needed = nvars - nexps; /* extra values needed */ | 549 | int needed = nvars - nexps; /* extra values needed */ |
| 550 | luaK_checkstack(fs, needed); | ||
| 550 | if (hasmultret(e->k)) { /* last expression has multiple returns? */ | 551 | if (hasmultret(e->k)) { /* last expression has multiple returns? */ |
| 551 | int extra = needed + 1; /* discount last expression itself */ | 552 | int extra = needed + 1; /* discount last expression itself */ |
| 552 | if (extra < 0) | 553 | if (extra < 0) |
diff --git a/testes/errors.lua b/testes/errors.lua index 4230a352..00a43fc6 100644 --- a/testes/errors.lua +++ b/testes/errors.lua | |||
| @@ -689,21 +689,26 @@ end | |||
| 689 | -- testing syntax limits | 689 | -- testing syntax limits |
| 690 | 690 | ||
| 691 | local function testrep (init, rep, close, repc, finalresult) | 691 | local function testrep (init, rep, close, repc, finalresult) |
| 692 | local s = init .. string.rep(rep, 100) .. close .. string.rep(repc, 100) | 692 | local function gencode (n) |
| 693 | local res, msg = load(s) | 693 | return init .. string.rep(rep, n) .. close .. string.rep(repc, n) |
| 694 | assert(res) -- 100 levels is OK | 694 | end |
| 695 | local res, msg = load(gencode(100)) -- 100 levels is OK | ||
| 696 | assert(res) | ||
| 695 | if (finalresult) then | 697 | if (finalresult) then |
| 696 | assert(res() == finalresult) | 698 | assert(res() == finalresult) |
| 697 | end | 699 | end |
| 698 | s = init .. string.rep(rep, 500) | 700 | local res, msg = load(gencode(500)) -- 500 levels not ok |
| 699 | local res, msg = load(s) -- 500 levels not ok | ||
| 700 | assert(not res and (string.find(msg, "too many") or | 701 | assert(not res and (string.find(msg, "too many") or |
| 701 | string.find(msg, "overflow"))) | 702 | string.find(msg, "overflow"))) |
| 702 | end | 703 | end |
| 703 | 704 | ||
| 705 | testrep("local a", ",a", ";", "") -- local variables | ||
| 706 | testrep("local a", ",a", "= 1", ",1") -- local variables initialized | ||
| 707 | testrep("local a", ",a", "= f()", "") -- local variables initialized | ||
| 704 | testrep("local a; a", ",a", "= 1", ",1") -- multiple assignment | 708 | testrep("local a; a", ",a", "= 1", ",1") -- multiple assignment |
| 705 | testrep("local a; a=", "{", "0", "}") | 709 | testrep("local a; a=", "{", "0", "}") -- constructors |
| 706 | testrep("return ", "(", "2", ")", 2) | 710 | testrep("return ", "(", "2", ")", 2) -- parentheses |
| 711 | -- nested calls (a(a(a(a(...))))) | ||
| 707 | testrep("local function a (x) return x end; return ", "a(", "2.2", ")", 2.2) | 712 | testrep("local function a (x) return x end; return ", "a(", "2.2", ")", 2.2) |
| 708 | testrep("", "do ", "", " end") | 713 | testrep("", "do ", "", " end") |
| 709 | testrep("", "while a do ", "", " end") | 714 | testrep("", "while a do ", "", " end") |
