[gcalctool] Catch overflow in MP conversion to string



commit 117a6d5e66764b71f14581453b4b52550448a98f
Author: Robert Ancell <robert ancell gmail com>
Date:   Fri May 8 09:58:58 2009 +1000

    Catch overflow in MP conversion to string
    Set state for unittest and --solve
---
 gcalctool/calctool.c   |    5 +++++
 gcalctool/mp-convert.c |   17 +++++++++++++++--
 gcalctool/unittest.c   |    3 +++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/gcalctool/calctool.c b/gcalctool/calctool.c
index e956b1e..d70dc4f 100644
--- a/gcalctool/calctool.c
+++ b/gcalctool/calctool.c
@@ -136,6 +136,11 @@ solve(const char *equation)
     MPNumber result;
     char result_str[MAXLINE];
     
+    v->base = DEC;
+    v->ttype = DEG;
+    v->wordlen = 32;
+    v->accuracy = 9;
+    
     error = ce_parse(equation, &result);
     if(error != 0) {
         fprintf(stderr, "Error %d\n", error);
diff --git a/gcalctool/mp-convert.c b/gcalctool/mp-convert.c
index 5514d8b..fac4c09 100644
--- a/gcalctool/mp-convert.c
+++ b/gcalctool/mp-convert.c
@@ -488,10 +488,11 @@ void
 mp_cast_to_string(char *target, int target_len, const MPNumber *MPnumber, int base, int accuracy)
 {
     static char digits[] = "0123456789ABCDEF";
-    char *optr, *start, *end, *last_non_zero;
+    char *optr, *start, *end, *stopper, *last_non_zero;
     MPNumber number, integer_component, fractional_component, MPbase, temp;
    
     optr = target;
+    stopper = target + target_len - 1;
 
     /* Insert sign */
     if (mp_is_negative(MPnumber)) {
@@ -524,13 +525,19 @@ mp_cast_to_string(char *target, int target_len, const MPNumber *MPnumber, int ba
        
         mp_subtract(&temp, &t2, &t3);
         mpcmim(&t3, &t3);
+
+        if (optr == stopper) {
+            mperr(_("Number too big to represent"));
+            *optr = '\0';
+            return;
+        }
         *optr++ = digits[mp_cast_to_int(&t3)];
        
         mp_set_from_mp(&t, &temp);
     } while (!mp_is_zero(&temp));
-    end = optr - 1;
    
     /* Reverse digits */
+    end = optr - 1;
     while(start < end) {
         char t;
         t = *start;
@@ -559,7 +566,13 @@ mp_cast_to_string(char *target, int target_len, const MPNumber *MPnumber, int ba
         mpcmim(&temp, &digit);
         d = mp_cast_to_int(&digit);
        
+        if (optr == stopper) {
+            mperr(_("Number too big to represent"));
+            *optr = '\0';
+            return;
+        }        
         *optr++ = digits[d];
+
         if(d != 0)
             last_non_zero = optr;
         mp_subtract(&temp, &digit, &temp);
diff --git a/gcalctool/unittest.c b/gcalctool/unittest.c
index 4b27c48..d0ee0dc 100644
--- a/gcalctool/unittest.c
+++ b/gcalctool/unittest.c
@@ -59,6 +59,9 @@ void
 test_parser()
 {
     v->base = DEC;
+    v->ttype = DEG;
+    v->wordlen = 32;
+    v->accuracy = 9;
 
     test("0", "0", 0);
     test("1", "1", 0);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]