summaryrefslogtreecommitdiff
path: root/mpz/realloc2.c
diff options
context:
space:
mode:
authorTorbjorn Granlund <tege@gmplib.org>2008-11-21 18:53:57 +0100
committerTorbjorn Granlund <tege@gmplib.org>2008-11-21 18:53:57 +0100
commit41b1404547508c9516998b7c03142cb8e1f72d5c (patch)
treedf6cb6e89b02edeef2dce51f02e73d776397dcdd /mpz/realloc2.c
parente8f3bd0cea4a4e383b2b153c5ef2bca8f3f6695e (diff)
downloadgmp-41b1404547508c9516998b7c03142cb8e1f72d5c.tar.gz
Rewrite to avoid internal overflow and to detect mpz_t overflow.
Diffstat (limited to 'mpz/realloc2.c')
-rw-r--r--mpz/realloc2.c20
1 files changed, 4 insertions, 16 deletions
diff --git a/mpz/realloc2.c b/mpz/realloc2.c
index 422c83890..9c03c8bfc 100644
--- a/mpz/realloc2.c
+++ b/mpz/realloc2.c
@@ -25,23 +25,12 @@ along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
void
mpz_realloc2 (mpz_ptr m, unsigned long bits)
{
- mp_ptr mp;
mp_size_t new_alloc;
- new_alloc = (bits + GMP_NUMB_BITS-1) / GMP_NUMB_BITS;
+ bits -= (bits != 0); /* Round down, except if 0 */
+ new_alloc = 1 + bits / GMP_NUMB_BITS;
- /* Never allocate zero space. */
- new_alloc = MAX (new_alloc, 1);
-
- if (sizeof (mp_size_t) == sizeof (int))
- {
- if (UNLIKELY (new_alloc > INT_MAX / GMP_NUMB_BITS))
- {
- fprintf (stderr, "gmp: overflow in mpz type\n");
- abort ();
- }
- }
- else
+ if (sizeof (unsigned long) > sizeof (int)) /* param vs _mp_size field */
{
if (UNLIKELY (new_alloc > INT_MAX))
{
@@ -50,8 +39,7 @@ mpz_realloc2 (mpz_ptr m, unsigned long bits)
}
}
- mp = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
- PTR(m) = mp;
+ PTR(m) = __GMP_REALLOCATE_FUNC_LIMBS (PTR(m), ALLOC(m), new_alloc);
ALLOC(m) = new_alloc;
/* Don't create an invalid number; if the current value doesn't fit after