aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
authorPaul Eggert2011-05-27 12:37:32 -0700
committerPaul Eggert2011-05-27 12:37:32 -0700
commit0f6990a78ae5016d8ae73253cdb4739adf0197e7 (patch)
tree78c7860e14d7cf6bc73526174493a02e606dfc13 /src/data.c
parentfb1ac845caea7da6ba98b93c3d67fa67c651b8ef (diff)
parentb57f7e0a357aacf98ec5be826f7227f37e9806b8 (diff)
downloademacs-0f6990a78ae5016d8ae73253cdb4739adf0197e7.tar.gz
emacs-0f6990a78ae5016d8ae73253cdb4739adf0197e7.zip
Merge: Integer overflow fixes.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/data.c b/src/data.c
index 577ae777d89..ce0e8e40f51 100644
--- a/src/data.c
+++ b/src/data.c
@@ -22,6 +22,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <signal.h> 22#include <signal.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <setjmp.h> 24#include <setjmp.h>
25
26#include <intprops.h>
27
25#include "lisp.h" 28#include "lisp.h"
26#include "puresize.h" 29#include "puresize.h"
27#include "character.h" 30#include "character.h"
@@ -2431,6 +2434,10 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2431 register EMACS_INT accum = 0; 2434 register EMACS_INT accum = 0;
2432 register EMACS_INT next; 2435 register EMACS_INT next;
2433 2436
2437 int overflow = 0;
2438 size_t ok_args;
2439 EMACS_INT ok_accum;
2440
2434 switch (SWITCH_ENUM_CAST (code)) 2441 switch (SWITCH_ENUM_CAST (code))
2435 { 2442 {
2436 case Alogior: 2443 case Alogior:
@@ -2451,25 +2458,48 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2451 2458
2452 for (argnum = 0; argnum < nargs; argnum++) 2459 for (argnum = 0; argnum < nargs; argnum++)
2453 { 2460 {
2461 if (! overflow)
2462 {
2463 ok_args = argnum;
2464 ok_accum = accum;
2465 }
2466
2454 /* Using args[argnum] as argument to CHECK_NUMBER_... */ 2467 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2455 val = args[argnum]; 2468 val = args[argnum];
2456 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val); 2469 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
2457 2470
2458 if (FLOATP (val)) 2471 if (FLOATP (val))
2459 return float_arith_driver ((double) accum, argnum, code, 2472 return float_arith_driver (ok_accum, ok_args, code,
2460 nargs, args); 2473 nargs, args);
2461 args[argnum] = val; 2474 args[argnum] = val;
2462 next = XINT (args[argnum]); 2475 next = XINT (args[argnum]);
2463 switch (SWITCH_ENUM_CAST (code)) 2476 switch (SWITCH_ENUM_CAST (code))
2464 { 2477 {
2465 case Aadd: 2478 case Aadd:
2479 if (INT_ADD_OVERFLOW (accum, next))
2480 {
2481 overflow = 1;
2482 accum &= INTMASK;
2483 }
2466 accum += next; 2484 accum += next;
2467 break; 2485 break;
2468 case Asub: 2486 case Asub:
2487 if (INT_SUBTRACT_OVERFLOW (accum, next))
2488 {
2489 overflow = 1;
2490 accum &= INTMASK;
2491 }
2469 accum = argnum ? accum - next : nargs == 1 ? - next : next; 2492 accum = argnum ? accum - next : nargs == 1 ? - next : next;
2470 break; 2493 break;
2471 case Amult: 2494 case Amult:
2472 accum *= next; 2495 if (INT_MULTIPLY_OVERFLOW (accum, next))
2496 {
2497 EMACS_UINT a = accum, b = next, ab = a * b;
2498 overflow = 1;
2499 accum = ab & INTMASK;
2500 }
2501 else
2502 accum *= next;
2473 break; 2503 break;
2474 case Adiv: 2504 case Adiv:
2475 if (!argnum) 2505 if (!argnum)
@@ -2501,6 +2531,9 @@ arith_driver (enum arithop code, size_t nargs, register Lisp_Object *args)
2501 } 2531 }
2502 } 2532 }
2503 2533
2534 accum &= INTMASK;
2535 if (MOST_POSITIVE_FIXNUM < accum)
2536 accum += MOST_NEGATIVE_FIXNUM - (MOST_POSITIVE_FIXNUM + 1);
2504 XSETINT (val, accum); 2537 XSETINT (val, accum);
2505 return val; 2538 return val;
2506} 2539}
@@ -2760,11 +2793,11 @@ In this case, zeros are shifted in on the left. */)
2760 if (XINT (count) >= BITS_PER_EMACS_INT) 2793 if (XINT (count) >= BITS_PER_EMACS_INT)
2761 XSETINT (val, 0); 2794 XSETINT (val, 0);
2762 else if (XINT (count) > 0) 2795 else if (XINT (count) > 0)
2763 XSETINT (val, (EMACS_UINT) XUINT (value) << XFASTINT (count)); 2796 XSETINT (val, XUINT (value) << XFASTINT (count));
2764 else if (XINT (count) <= -BITS_PER_EMACS_INT) 2797 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2765 XSETINT (val, 0); 2798 XSETINT (val, 0);
2766 else 2799 else
2767 XSETINT (val, (EMACS_UINT) XUINT (value) >> -XINT (count)); 2800 XSETINT (val, XUINT (value) >> -XINT (count));
2768 return val; 2801 return val;
2769} 2802}
2770 2803