[svn:parrot] r38028 - in trunk/src: pmc string

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Fri Apr 10 19:33:06 UTC 2009


Author: whiteknight
Date: Fri Apr 10 19:33:05 2009
New Revision: 38028
URL: https://trac.parrot.org/parrot/changeset/38028

Log:
Fix Parrot_str_to_int to detect overflow and throw an EXCEPTION_ERR_OVERFLOW.

Modified:
   trunk/src/pmc/integer.pmc
   trunk/src/string/api.c

Modified: trunk/src/pmc/integer.pmc
==============================================================================
--- trunk/src/pmc/integer.pmc	Fri Apr 10 17:48:14 2009	(r38027)
+++ trunk/src/pmc/integer.pmc	Fri Apr 10 19:33:05 2009	(r38028)
@@ -135,7 +135,8 @@
             ? constant_pmc_new(INTERP, type)
             : pmc_new(INTERP, type);
 
-        /* RT #46623 bigint overflow */
+        /* Parrot_str_to_int catches overflow automatically, so we don't need to
+           worry about it here. */
         VTABLE_set_integer_native(INTERP, res, Parrot_str_to_int(INTERP, rep));
         return res;
     }

Modified: trunk/src/string/api.c
==============================================================================
--- trunk/src/string/api.c	Fri Apr 10 17:48:14 2009	(r38027)
+++ trunk/src/string/api.c	Fri Apr 10 19:33:05 2009	(r38028)
@@ -2025,7 +2025,7 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 INTVAL
-Parrot_str_to_int(SHIM_INTERP, ARGIN_NULLOK(const STRING *s))
+Parrot_str_to_int(PARROT_INTERP, ARGIN_NULLOK(const STRING *s))
 {
     ASSERT_ARGS(Parrot_str_to_int)
     if (s == NULL)
@@ -2033,6 +2033,8 @@
     {
         const char         *start     = s->strstart;
         const char * const  end       = start + s->bufused;
+        const INTVAL        max_safe  = PARROT_INTVAL_MAX / 10;
+        const INTVAL        last_dig  = PARROT_INTVAL_MAX % 10;
         int                 sign      = 1;
         INTVAL              in_number = 0;
         INTVAL              i         = 0;
@@ -2043,8 +2045,13 @@
             const unsigned char c = *start;
 
             if (isdigit((unsigned char)c)) {
+                const INTVAL nextval = c - '0';
                 in_number = 1;
-                i         = i * 10 + (c - '0');
+                if(i < max_safe || (i == max_safe && nextval <= last_dig))
+                    i = i * 10 + nextval;
+                else
+                    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ERR_OVERFLOW,
+                        "Integer value of String '%S' too big", s);
             }
             else if (!in_number) {
                 /* we've not yet seen any digits */


More information about the parrot-commits mailing list