summaryrefslogtreecommitdiff
path: root/mpz/inp_raw.c
diff options
context:
space:
mode:
authorTorbjorn Granlund <tg@gmplib.org>2016-11-29 01:28:04 +0100
committerTorbjorn Granlund <tg@gmplib.org>2016-11-29 01:28:04 +0100
commit7c75935c462cd05737687db3f5a86a233459c635 (patch)
treef138d4141e3edba3308335589ee8401dff94e7b9 /mpz/inp_raw.c
parentf88d50b656e66ac0209351649a612b7445d0c097 (diff)
downloadgmp-7c75935c462cd05737687db3f5a86a233459c635.tar.gz
Rewrite size computation to avoid overflow.
Diffstat (limited to 'mpz/inp_raw.c')
-rw-r--r--mpz/inp_raw.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/mpz/inp_raw.c b/mpz/inp_raw.c
index 7014df977..378c42bb4 100644
--- a/mpz/inp_raw.c
+++ b/mpz/inp_raw.c
@@ -1,6 +1,6 @@
/* mpz_inp_raw -- read an mpz_t in raw format.
-Copyright 2001, 2002, 2005, 2012 Free Software Foundation, Inc.
+Copyright 2001, 2002, 2005, 2012, 2016 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -65,6 +65,7 @@ mpz_inp_raw (mpz_ptr x, FILE *fp)
{
unsigned char csize_bytes[4];
mp_size_t csize, abs_xsize, i;
+ size_t size;
size_t abs_csize;
char *cp;
mp_ptr xp, sp, ep;
@@ -77,17 +78,13 @@ mpz_inp_raw (mpz_ptr x, FILE *fp)
if (fread (csize_bytes, sizeof (csize_bytes), 1, fp) != 1)
return 0;
- csize =
- ( (mp_size_t) csize_bytes[0] << 24)
- + ((mp_size_t) csize_bytes[1] << 16)
- + ((mp_size_t) csize_bytes[2] << 8)
- + ((mp_size_t) csize_bytes[3]);
-
- /* Sign extend if necessary.
- Could write "csize -= ((csize & 0x80000000L) << 1)", but that tickles a
- bug in gcc 3.0 for powerpc64 on AIX. */
- if (sizeof (csize) > 4 && csize & 0x80000000L)
- csize -= 0x80000000L << 1;
+ size = (((size_t) csize_bytes[0] << 24) + ((size_t) csize_bytes[1] << 16) +
+ ((size_t) csize_bytes[2] << 8) + ((size_t) csize_bytes[3]));
+
+ if (size < 0x80000000u)
+ csize = size;
+ else
+ csize = size - 0x80000000u - 0x80000000u;
abs_csize = ABS (csize);