gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog testsuite/actionscript.all/Glob...


From: Benjamin Wolsey
Subject: [Gnash-commit] gnash ChangeLog testsuite/actionscript.all/Glob...
Date: Tue, 18 Mar 2008 22:47:39 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Benjamin Wolsey <bwy>   08/03/18 22:47:38

Modified files:
        .              : ChangeLog 
        testsuite/actionscript.all: Global.as 
        server/asobj   : Global.cpp 

Log message:
                * testsuite/actionscript.all/Global.as: add more parseInt tests 
showing
                  some errors with hexadecimal parsing.
                * server/asobj/Global.cpp: rewrite parseInt to deal with most 
of the
                  main cases correctly.
        
        There are some wacky cases with long strings and high bases that
        still aren't right. I haven't worked out whether there's some
        sense in the madness yet.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5967&r2=1.5968
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Global.as?cvsroot=gnash&r1=1.46&r2=1.47
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Global.cpp?cvsroot=gnash&r1=1.96&r2=1.97

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5967
retrieving revision 1.5968
diff -u -b -r1.5967 -r1.5968
--- ChangeLog   18 Mar 2008 18:36:21 -0000      1.5967
+++ ChangeLog   18 Mar 2008 22:47:37 -0000      1.5968
@@ -1,5 +1,12 @@
 2008-03-18 Benjamin Wolsey <address@hidden>
 
+       * testsuite/actionscript.all/Global.as: add more parseInt tests showing
+         some errors with hexadecimal parsing.
+       * server/asobj/Global.cpp: rewrite parseInt to deal with most of the
+         main cases correctly.
+
+2008-03-18 Benjamin Wolsey <address@hidden>
+
        * testsuite/swfdec/swfdec_gnash_tester: don't use fromdos. It's
          not always available and seems to be unnecessary.
 

Index: testsuite/actionscript.all/Global.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Global.as,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- testsuite/actionscript.all/Global.as        18 Mar 2008 14:01:00 -0000      
1.46
+++ testsuite/actionscript.all/Global.as        18 Mar 2008 22:47:38 -0000      
1.47
@@ -22,7 +22,7 @@
 // execute it like this gnash -1 -r 0 -v out.swf
 
 
-rcsid="$Id: Global.as,v 1.46 2008/03/18 14:01:00 bwy Exp $";
+rcsid="$Id: Global.as,v 1.47 2008/03/18 22:47:38 bwy Exp $";
 #include "check.as"
 
 #if OUTPUT_VERSION > 5
@@ -63,16 +63,31 @@
 check_equals(typeof(ASSetNativeAccessor), 'function');
 
 // Test parseInt
-check ( parseInt('45b') == 45 );
-check ( parseInt('65') == 65 );
-check ( parseInt('-1234') == -1234 );
-check ( parseInt('-1.234') == -1 );
+check_equals ( parseInt('45b'), 45 );
+check_equals ( parseInt('65'), 65 );
+check_equals ( parseInt('-1234'), -1234 );
+check_equals ( parseInt('-1.234'), -1 );
+check_equals ( parseInt('        -1234'), -1234 );
+check_equals ( parseInt('          +12.34'), 12 );
+check_equals ( parseInt("           234"), 234 );
+check ( isNaN(parseInt('++3')));
+
 // Test parseint with hex
+// No whitespace allowed. Sign must come after0x
 check ( parseInt('0x111') == 273 );
 check ( isNaN(parseInt('0xw')));
+check ( isNaN(parseInt('-0x111')));
+check ( isNaN(parseInt('+0x111')));
+check ( parseInt(' 0x111') == 0 );
+check ( parseInt('0x-111') == -273 );
+check ( parseInt('0x+111') == 273 );
+check ( parseInt('0X-111') == -273 );
+check ( parseInt('0X+111') == 273 );
+
 // Test parseint with octal
 check_equals (parseInt('0352'), 234 );
 check_equals (parseInt('-0352'), -234);
+check_equals (parseInt('+0352'), 234);
 // Evidently only numbers with no whitespace in front and
 // no digits higher than 7 are octal. These all decimal:
 check_equals (parseInt('07658'), 7658);
@@ -96,6 +111,12 @@
 o = {}; o.toString = function() { return "12"; };
 check_equals (parseInt(o), 12);
 
+check(isNaN(parseInt("8589934592", 5)));
+
+// Er...
+xcheck_equals(parseInt("8589934592", 16), 573538780562);
+xcheck_equals(parseInt("800000000", 36), 22568879259648);
+
 // It's not reliable to compare a double type with ==, so we'll give it a
 // small range using >= and <=
 check ( isNaN(parseFloat('test')) );
@@ -385,15 +406,15 @@
 //------------------------------------------------------------
 
 #if OUTPUT_VERSION == 5
-       check_totals(98); // SWF5
+       check_totals(113); // SWF5
 #else
 # if OUTPUT_VERSION == 6
-       check_totals(132); // SWF6
+       check_totals(147); // SWF6
 # else
 #  if OUTPUT_VERSION == 7
-       check_totals(114); // SWF7
+       check_totals(129); // SWF7
 #  else
-       check_totals(101); // SWF8+
+       check_totals(116); // SWF8+
 #  endif
 # endif
 #endif

Index: server/asobj/Global.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Global.cpp,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- server/asobj/Global.cpp     6 Mar 2008 16:17:43 -0000       1.96
+++ server/asobj/Global.cpp     18 Mar 2008 22:47:38 -0000      1.97
@@ -187,6 +187,17 @@
     return rv;
 }
 
+// The second argument, if supplied, is the base.
+// If none is supplied, we have to work out the 
+// base from the string. Decimal, octal and hexadecimal are
+// possible, according to the following rules:
+// 1. If the string starts with 0x or 0X, the number is hex.
+// 2. The 0x or 0X may be *followed* by '-' or '+' to indicate sign. A number
+//    with no sign is positive.
+// 3. If the string starts with 0, -0 or +0 and contains only the characters
+//    0-7.
+// 4. If the string starts with *any* other sequence of characters, including
+//    whitespace, it is decimal.
 static as_value
 as_global_parseint(const fn_call& fn)
 {
@@ -202,32 +213,20 @@
             log_aserror(_("%s has more than two arguments"), __FUNCTION__);
     )
 
+    const std::string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
     const std::string& expr = fn.arg(0).to_string();
     
-    int base = 10;
-    const std::string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-    bool bNegative = false;
+    bool negative = false;
+    int base = 0;
   
     std::string::const_iterator it = expr.begin();
 
-    // Skip leading whitespace
-    while(*it == ' ' || *it == '\n' || *it == '\t' || *it == '\r')
-    {
-        ++it;
-    }
-
-    // Is the first non-whitespace character a minus?
-    if (*it == '-')
-    {
-        bNegative = true;
-       ++it;
-    }
 
     // if we were sent a second argument, that's our base
     if (fn.nargs > 1)
     {
-       // to_number returns a double. atoi() would be better
-       base = (int)(fn.arg(1).to_number());
+           base = (fn.arg(1).to_int());
        
        // Bases from 2 to 36 are valid, otherwise return NaN
         if (base < 2 || base > 36)
@@ -236,48 +235,85 @@
            rv.set_nan();
            return rv;
         }      
-
     }
-
-    // If the string starts with '0x':
-    else if (expr.end() - it >= 2 &&
-               (*it == '0' && toupper(*(it + 1)) == 'X' ))
+    else
+    {
+        // Try hexadecimal first
+        if (expr.substr(0, 2) == "0x" || expr.substr(0, 2) == "0X")
     {
-        // the base is 16
        base = 16;
-        // Move to the digit after the 'x'
        it += 2; 
+            
+            if (*it == '-')
+            {
+                negative = true;
+                it++;
+            }
+            else if (*it == '+') 
+            {
+                it++;
     }
+        }
+        // Either octal or decimal.
+        else if (*it == '0' || *it == '-' || *it == '+')
+        {
+
+            base = 8;
 
-    // Octal if the string starts with "0" then an octal digit, but
-    // *only* if there is no whitespace before it; in that case decimal.
-    else if (it - expr.begin() == (bNegative ? 1 : 0))
-    {
-        if (expr.end() - it >= 2 && 
-               *it == '0' && isdigit(*(it + 1)))
-        {
-            // And if there are any chars other than 0-7, it's *still* a
-            // base 10 number...
-            // At least we know where we are in the string, so can use
-            // string methods.
-           if (expr.find_first_not_of("01234567", (bNegative ? 1 : 0)) !=
+            // Check for negative and move to the next digit
+            if (*it == '-')
+            {
+                negative = true;
+                it++;
+            }
+            else if (*it == '+') it++;
+            
+            if (*it != '0') base = 10;
+            
+            // Check for expectional case "-0x" or "+0x", which
+            // return NaN
+            else if (std::toupper(*(it + 1)) == 'X')
+            {
+                   as_value rv;
+                   rv.set_nan();
+                   return rv;
+            }
+            
+            // Check from the current position for non-octal characters;
+            // it's decimal in that case.
+            else if (expr.find_first_not_of("01234567", it - expr.begin()) !=
                std::string::npos)
            {
                base = 10;
            }
-           else base = 8;
+        }
+        // Everything else is decimal.
+        else
+        {
+            base = 10;
 
-           // Point the iterator to the first digit after the '0'.
+            // Skip leading whitespace
+            while(*it == ' ' || *it == '\n' || *it == '\t' || *it == '\r')
+            {
            ++it;
-
+            }
+            if (*it == '-')
+            {
+                negative = true;
+                it++;
+            }
+            else if (*it == '+') it++;
         }
     }
 
+    // Now we have the base, parse the digits. The iterator should
+    // be pointing at the first digit.
+    
     // Check to see if the first digit is valid, otherwise 
     // return NaN.
     int digit = digits.find(toupper(*it));
 
-    if (digit >= base)
+    if (digit >= base || digit < 0)
     {
            as_value rv;
            rv.set_nan();
@@ -298,7 +334,7 @@
            ++it;
     }
 
-    if (bNegative)
+    if (negative)
        result = -result;
     
     // Now return the parsed string as an integer.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]