summaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-12-16 12:30:22 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-12-16 12:30:22 -0200
commita8f8c7fd80a5c7e630fd4bf7f858d05024f6b434 (patch)
treeb5193ced2c4516a8fe4c6a5af05e0d7d5c27d49c /lvm.c
parent1a19893d6f8ee16944168a3f2c99002f70522f4c (diff)
downloadlua-a8f8c7fd80a5c7e630fd4bf7f858d05024f6b434.tar.gz
lua-a8f8c7fd80a5c7e630fd4bf7f858d05024f6b434.tar.bz2
lua-a8f8c7fd80a5c7e630fd4bf7f858d05024f6b434.zip
integer exponentiation with negative exponent is invalid
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/lvm.c b/lvm.c
index cba196b0..354f40d9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.179 2013/08/27 18:53:35 roberto Exp roberto $ 2** $Id: lvm.c,v 2.180 2013/08/29 13:49:57 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -333,8 +333,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) {
333 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ 333 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
334 if (y == 0) 334 if (y == 0)
335 luaG_runerror(L, "attempt to divide by zero"); 335 luaG_runerror(L, "attempt to divide by zero");
336 else /* -1 */ 336 return intop(-, 0, x); /* y==-1; avoid overflow with 0x80000...//-1 */
337 return intop(-, 0, x); /* avoid overflow with 0x80000... */
338 } 337 }
339 else { 338 else {
340 lua_Integer d = x / y; /* perform division */ 339 lua_Integer d = x / y; /* perform division */
@@ -350,8 +349,7 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
350 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ 349 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
351 if (y == 0) 350 if (y == 0)
352 luaG_runerror(L, "attempt to perform 'n%%0'"); 351 luaG_runerror(L, "attempt to perform 'n%%0'");
353 else /* -1 */ 352 return 0; /* y==-1; avoid overflow with 0x80000...%-1 */
354 return 0; /* avoid overflow with 0x80000... */
355 } 353 }
356 else { 354 else {
357 lua_Integer r = x % y; 355 lua_Integer r = x % y;
@@ -363,16 +361,21 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
363} 361}
364 362
365 363
366lua_Integer luaV_pow (lua_Integer x, lua_Integer y) { 364lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) {
367 lua_Integer r = 1; 365 if (y <= 0) { /* special cases: 0 or negative exponent */
368 lua_assert(y >= 0); 366 if (y < 0)
369 if (y == 0) return r; 367 luaG_runerror(L, "integer exponentiation with negative exponent");
370 for (; y > 1; y >>= 1) { 368 return 1; /* x^0 == 1 */
371 if (y & 1) r = intop(*, r, x); 369 }
372 x = intop(*, x, x); 370 else {
371 lua_Integer r = 1;
372 for (; y > 1; y >>= 1) {
373 if (y & 1) r = intop(*, r, x);
374 x = intop(*, x, x);
375 }
376 r = intop(*, r, x);
377 return r;
373 } 378 }
374 r = intop(*, r, x);
375 return r;
376} 379}
377 380
378 381
@@ -685,11 +688,9 @@ void luaV_execute (lua_State *L) {
685 TValue *rb = RKB(i); 688 TValue *rb = RKB(i);
686 TValue *rc = RKC(i); 689 TValue *rc = RKC(i);
687 lua_Number nb; lua_Number nc; 690 lua_Number nb; lua_Number nc;
688 lua_Integer ic; 691 if (ttisinteger(rb) && ttisinteger(rc)) {
689 if (ttisinteger(rb) && ttisinteger(rc) && 692 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
690 (ic = ivalue(rc)) >= 0) { 693 setivalue(ra, luaV_pow(L, ib, ic));
691 lua_Integer ib = ivalue(rb);
692 setivalue(ra, luaV_pow(ib, ic));
693 } 694 }
694 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { 695 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
695 setnvalue(ra, luai_numpow(L, nb, nc)); 696 setnvalue(ra, luai_numpow(L, nb, nc));