[Gnucash-changes] tweak yet another possible overflow path
Linas Vepstas
linas at cvs.gnucash.org
Fri Jul 2 21:49:22 EDT 2004
Log Message:
-----------
tweak yet another possible overflow path
Modified Files:
--------------
gnucash/src/engine:
gnc-numeric.c
Revision Data
-------------
Index: gnc-numeric.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -Lsrc/engine/gnc-numeric.c -Lsrc/engine/gnc-numeric.c -u -r1.51 -r1.52
--- src/engine/gnc-numeric.c
+++ src/engine/gnc-numeric.c
@@ -421,7 +421,7 @@
gint64 denom, gint how)
{
gnc_numeric product, result;
- qofint128 bigprod;
+ qofint128 bignume, bigdeno;
if(gnc_numeric_check(a) || gnc_numeric_check(b)) {
return gnc_numeric_error(GNC_ERROR_ARG);
@@ -453,19 +453,24 @@
b.denom = 1;
}
- bigprod = mult128 (a.num, b.num);
+ bignume = mult128 (a.num, b.num);
+ bigdeno = mult128 (a.denom, b.denom);
product.num = a.num*b.num;
product.denom = a.denom*b.denom;
/* If it looks to be overflowing, try to reduce the fraction ... */
- if (bigprod.isbig)
+ if (bignume.isbig || bigdeno.isbig)
{
/* If rounding allowed, then shift until there's no
* more overflow. The conversion at the end will fix
- * things up for the final value. */
+ * things up for the final value. Else overflow. */
if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
{
- product = reduce128 (bigprod, product.denom);
+ if (bigdeno.isbig)
+ {
+ return gnc_numeric_error (GNC_ERROR_OVERFLOW);
+ }
+ product = reduce128 (bignume, product.denom);
if (gnc_numeric_check (product))
{
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
@@ -473,13 +478,15 @@
}
else
{
- while (bigprod.isbig)
+ while (bignume.isbig || bigdeno.isbig)
{
- bigprod = shift128 (bigprod);
- product.denom >>= 1;
+ bignume = shift128 (bignume);
+ bigdeno = shift128 (bigdeno);
}
- product.num = bigprod.lo;
- if (bigprod.isneg) product.num = -product.num;
+ product.num = bignume.lo;
+ if (bignume.isneg) product.num = -product.num;
+
+ product.denom = bigdeno.lo;
if (0 == product.denom)
{
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
More information about the gnucash-changes
mailing list