diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-03-02 13:24:06 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-03-02 13:24:06 -0300 |
| commit | e4607523234f16ed9ed0436340b9315377dbfe7f (patch) | |
| tree | ef792ad6ad9bd869c60b9a31539234e04dfa024a | |
| parent | 92594f09395800f6f085ca7501ffd1f7aef25e22 (diff) | |
| download | lua-e4607523234f16ed9ed0436340b9315377dbfe7f.tar.gz lua-e4607523234f16ed9ed0436340b9315377dbfe7f.tar.bz2 lua-e4607523234f16ed9ed0436340b9315377dbfe7f.zip | |
Fixed "conceptual" bug in 'luaK_setreturns'
This function was computing invalid instruction addresses when the
expression was not a multi-return instruction. (Virtually all machines
don't raise errors when computing an invalid address, as long as the
address is not accessed, but this computation is undefined behavior in
ISO C.)
| -rw-r--r-- | lcode.c | 7 | ||||
| -rw-r--r-- | lparser.c | 3 |
2 files changed, 5 insertions, 5 deletions
| @@ -703,19 +703,18 @@ static void const2exp (TValue *v, expdesc *e) { | |||
| 703 | 703 | ||
| 704 | /* | 704 | /* |
| 705 | ** Fix an expression to return the number of results 'nresults'. | 705 | ** Fix an expression to return the number of results 'nresults'. |
| 706 | ** Either 'e' is a multi-ret expression (function call or vararg) | 706 | ** 'e' must be a multi-ret expression (function call or vararg). |
| 707 | ** or 'nresults' is LUA_MULTRET (as any expression can satisfy that). | ||
| 708 | */ | 707 | */ |
| 709 | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { | 708 | void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { |
| 710 | Instruction *pc = &getinstruction(fs, e); | 709 | Instruction *pc = &getinstruction(fs, e); |
| 711 | if (e->k == VCALL) /* expression is an open function call? */ | 710 | if (e->k == VCALL) /* expression is an open function call? */ |
| 712 | SETARG_C(*pc, nresults + 1); | 711 | SETARG_C(*pc, nresults + 1); |
| 713 | else if (e->k == VVARARG) { | 712 | else { |
| 713 | lua_assert(e->k == VVARARG); | ||
| 714 | SETARG_C(*pc, nresults + 1); | 714 | SETARG_C(*pc, nresults + 1); |
| 715 | SETARG_A(*pc, fs->freereg); | 715 | SETARG_A(*pc, fs->freereg); |
| 716 | luaK_reserveregs(fs, 1); | 716 | luaK_reserveregs(fs, 1); |
| 717 | } | 717 | } |
| 718 | else lua_assert(nresults == LUA_MULTRET); | ||
| 719 | } | 718 | } |
| 720 | 719 | ||
| 721 | 720 | ||
| @@ -1014,7 +1014,8 @@ static void funcargs (LexState *ls, expdesc *f, int line) { | |||
| 1014 | args.k = VVOID; | 1014 | args.k = VVOID; |
| 1015 | else { | 1015 | else { |
| 1016 | explist(ls, &args); | 1016 | explist(ls, &args); |
| 1017 | luaK_setmultret(fs, &args); | 1017 | if (hasmultret(args.k)) |
| 1018 | luaK_setmultret(fs, &args); | ||
| 1018 | } | 1019 | } |
| 1019 | check_match(ls, ')', '(', line); | 1020 | check_match(ls, ')', '(', line); |
| 1020 | break; | 1021 | break; |
