[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

darin darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:25:08 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit a51d07b4e25432a767e2ca3c0f915c1343721702
Author: darin <darin at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Feb 2 21:23:17 2004 +0000

            Reviewed by Maciej.
    
            - fixed <rdar://problem/3519285>: integer operations on large negative numbers yield bad results (discovered with "HTMLCrypt")
            - fixed other related overflow issues
    
            * kjs/value.h: Changed return types of toInteger, toInt32, toUInt32, and toUInt16.
            * kjs/value.cpp:
            (ValueImp::toInteger): Change to return a double, since this operation, from the ECMA specification,
            must not restrict values to the range of a particular integer type.
            (ValueImp::toInt32): Used a sized integer type for the result of this function, and also added
            proper handling for negative results from fmod.
            (ValueImp::toUInt32): Ditto.
            (ValueImp::toUInt16): Ditto.
            (ValueImp::dispatchToUInt32): Changed result type from unsigned to uint32_t.
    
            * kjs/array_object.cpp: (ArrayProtoFuncImp::call): Use a double instead of an int to handle
            out-of-integer-range values better in the slice function.
            * kjs/internal.cpp: (KJS::roundValue): Streamline the function, handling NAN and infinity properly.
            * kjs/number_object.cpp: (NumberProtoFuncImp::call): Use a double instead of an int to handle
            out-of-integer-range values better in the toString function.
            * kjs/string_object.cpp: (StringProtoFuncImp::call): Use a double instead of an int to handle
            out-of-integer-range values better in the charAt, charCodeAt, indexOf, lastIndexOf, slice,
            and substr functions.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6025 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index f0b77e9..0e87136 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,29 @@
+2004-02-02  Darin Adler  <darin at apple.com>
+
+        Reviewed by Maciej.
+
+        - fixed <rdar://problem/3519285>: integer operations on large negative numbers yield bad results (discovered with "HTMLCrypt")
+        - fixed other related overflow issues
+
+        * kjs/value.h: Changed return types of toInteger, toInt32, toUInt32, and toUInt16.
+        * kjs/value.cpp:
+        (ValueImp::toInteger): Change to return a double, since this operation, from the ECMA specification,
+        must not restrict values to the range of a particular integer type.
+        (ValueImp::toInt32): Used a sized integer type for the result of this function, and also added
+        proper handling for negative results from fmod.
+        (ValueImp::toUInt32): Ditto.
+        (ValueImp::toUInt16): Ditto.
+        (ValueImp::dispatchToUInt32): Changed result type from unsigned to uint32_t.
+
+        * kjs/array_object.cpp: (ArrayProtoFuncImp::call): Use a double instead of an int to handle
+        out-of-integer-range values better in the slice function.
+        * kjs/internal.cpp: (KJS::roundValue): Streamline the function, handling NAN and infinity properly.
+        * kjs/number_object.cpp: (NumberProtoFuncImp::call): Use a double instead of an int to handle
+        out-of-integer-range values better in the toString function.
+        * kjs/string_object.cpp: (StringProtoFuncImp::call): Use a double instead of an int to handle
+        out-of-integer-range values better in the charAt, charCodeAt, indexOf, lastIndexOf, slice,
+        and substr functions.
+
 === Safari-126 ===
 
 2004-01-30  Richard Williamson   <rjw at apple.com>
diff --git a/JavaScriptCore/kjs/array_object.cpp b/JavaScriptCore/kjs/array_object.cpp
index 904ea38..7aa481d 100644
--- a/JavaScriptCore/kjs/array_object.cpp
+++ b/JavaScriptCore/kjs/array_object.cpp
@@ -580,24 +580,33 @@ Value ArrayProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args
     // We return a new array
     Object resObj = Object::dynamicCast(exec->interpreter()->builtinArray().construct(exec,List::empty()));
     result = resObj;
-    int begin = args[0].toInteger(exec);
-    if ( begin < 0 )
-      begin = maxInt( begin + length, 0 );
-    else
-      begin = minInt( begin, length );
-    int end = length;
-    if (args[1].type() != UndefinedType)
-    {
+    double begin = args[0].toInteger(exec);
+    if (begin < 0) {
+      begin += length;
+      if (begin < 0)
+        begin = 0;
+    } else {
+      if (begin > length)
+        begin = length;
+    }
+    double end = length;
+    if (args[1].type() != UndefinedType) {
       end = args[1].toInteger(exec);
-      if ( end < 0 )
-        end = maxInt( end + length, 0 );
-      else
-        end = minInt( end, length );
+      if (end < 0) {
+        end += length;
+        if (end < 0)
+          end = 0;
+      } else {
+        if (end > length)
+          end = length;
+      }
     }
 
     //printf( "Slicing from %d to %d \n", begin, end );
     int n = 0;
-    for(int k = begin; k < end; k++, n++) {
+    int b = static_cast<int>(begin);
+    int e = static_cast<int>(end);
+    for(int k = b; k < e; k++, n++) {
       if (thisObj.hasProperty(exec, k)) {
         Value obj = thisObj.get(exec, k);
         resObj.put(exec, n, obj);
diff --git a/JavaScriptCore/kjs/internal.cpp b/JavaScriptCore/kjs/internal.cpp
index 05e41a5..7e98eb9 100644
--- a/JavaScriptCore/kjs/internal.cpp
+++ b/JavaScriptCore/kjs/internal.cpp
@@ -960,16 +960,12 @@ Boolean InternalFunctionImp::hasInstance(ExecState *exec, const Value &value)
 
 double KJS::roundValue(ExecState *exec, const Value &v)
 {
-  if (v.type() == UndefinedType) /* TODO: see below */
-    return 0.0;
   Number n = v.toNumber(exec);
-  if (n.value() == 0.0)   /* TODO: -0, NaN, Inf */
-    return 0.0;
-  double d = floor(fabs(n.value()));
-  if (n.value() < 0)
-    d *= -1;
-
-  return d;
+  double d = n.value();
+  double ad = fabs(d);
+  if (ad == 0 || isNaN(d) || isInf(d))
+    return d;
+  return copysign(floor(ad), d);
 }
 
 #ifndef NDEBUG
diff --git a/JavaScriptCore/kjs/number_object.cpp b/JavaScriptCore/kjs/number_object.cpp
index 29d59ac..c623ab2 100644
--- a/JavaScriptCore/kjs/number_object.cpp
+++ b/JavaScriptCore/kjs/number_object.cpp
@@ -92,12 +92,13 @@ Value NumberProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
   Value v = thisObj.internalValue();
   switch (id) {
   case ToString: {
-    int radix = 10;
+    double dradix = 10;
     if (!args.isEmpty() && args[0].type() != UndefinedType)
-      radix = args[0].toInteger(exec);
-    if (radix < 2 || radix > 36 || radix == 10)
+      dradix = args[0].toInteger(exec);
+    if (dradix < 2 || dradix > 36 || dradix == 10)
       result = String(v.toString(exec));
     else {
+      int radix = static_cast<int>(radix);
       unsigned i = v.toUInt32(exec);
       char s[33];
       char *p = s + sizeof(s);
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index df2acc2..877e9e6 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -186,9 +186,9 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
     return String(thisObj.internalValue().toString(exec));
   }
 
-  int n, m;
   UString u, u2, u3;
   int pos, p0, i;
+  double dpos;
   double d = 0.0;
 
   UString s = thisObj.toString(exec);
@@ -203,19 +203,19 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
     // handled above
     break;
   case CharAt:
-    pos = a0.toInteger(exec);
-    if (pos < 0 || pos >= len)
+    dpos = a0.toInteger(exec);
+    if (dpos < 0 || dpos >= len)
       u = "";
     else
-      u = s.substr(pos, 1);
+      u = s.substr(static_cast<int>(dpos), 1);
     result = String(u);
     break;
   case CharCodeAt:
-    pos = a0.toInteger(exec);
-    if (pos < 0 || pos >= len)
+    dpos = a0.toInteger(exec);
+    if (dpos < 0 || dpos >= len)
       d = NaN;
     else {
-      UChar c = s[pos];
+      UChar c = s[static_cast<int>(dpos)];
       d = (c.high() << 8) + c.low();
     }
     result = Number(d);
@@ -231,22 +231,30 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
   case IndexOf:
     u2 = a0.toString(exec);
     if (a1.type() == UndefinedType)
-      pos = 0;
-    else
-      pos = a1.toInteger(exec);
-    d = s.find(u2, pos);
+      dpos = 0;
+    else {
+      dpos = a1.toInteger(exec);
+      if (dpos < 0)
+        dpos = 0;
+      else if (dpos > len)
+        dpos = len;
+    }
+    d = s.find(u2, static_cast<int>(dpos));
     result = Number(d);
     break;
   case LastIndexOf:
     u2 = a0.toString(exec);
     d = a1.toNumber(exec);
-    if (a1.type() == UndefinedType || KJS::isNaN(d) || KJS::isPosInf(d))
-      pos = len;
-    else
-      pos = a1.toInteger(exec);
-    if (pos < 0)
-      pos = 0;
-    d = s.rfind(u2, pos);
+    if (a1.type() == UndefinedType || KJS::isNaN(d))
+      dpos = len;
+    else {
+      dpos = a1.toInteger(exec);
+      if (dpos < 0)
+        dpos = 0;
+      else if (dpos > len)
+        dpos = len;
+    }
+    d = s.rfind(u2, static_cast<int>(dpos));
     result = Number(d);
     break;
   case Match:
@@ -377,21 +385,29 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
   case Slice: // http://developer.netscape.com/docs/manuals/js/client/jsref/string.htm#1194366
     {
         // The arg processing is very much like ArrayProtoFunc::Slice
-        int begin = args[0].toUInt32(exec);
-        if (begin < 0)
-          begin = maxInt(begin + len, 0);
-        else
-          begin = minInt(begin, len);
-        int end = len;
+        double begin = args[0].toInteger(exec);
+        if (begin < 0) {
+          begin += len;
+          if (begin < 0)
+            begin = 0;
+        } else {
+          if (begin > len)
+            begin = len;
+        }
+        double end = len;
         if (args[1].type() != UndefinedType) {
           end = args[1].toInteger(exec);
-          if (end < 0)
-            end = maxInt(len + end, 0);
-          else
-            end = minInt(end, len);
+          if (end < 0) {
+            end += len;
+            if (end < 0)
+              end = 0;
+          } else {
+            if (end > len)
+              end = len;
+          }
         }
         //printf( "Slicing from %d to %d \n", begin, end );
-        result = String(s.substr(begin, end-begin));
+        result = String(s.substr(static_cast<int>(begin), static_cast<int>(end-begin)));
         break;
     }
     case Split: {
@@ -451,18 +467,22 @@ Value StringProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &arg
     }
     break;
   case Substr: {
-    n = a0.toInteger(exec);
-    m = a1.toInteger(exec);
-    int d, d2;
-    if (n >= 0)
-      d = n;
-    else
-      d = maxInt(len + n, 0);
+    double d = a0.toInteger(exec);
+    double d2 = a1.toInteger(exec);
+    if (d < 0) {
+      d += len;
+      if (d < 0)
+        d = 0;
+    }
     if (a1.type() == UndefinedType)
       d2 = len - d;
-    else
-      d2 = minInt(maxInt(m, 0), len - d);
-    result = String(s.substr(d, d2));
+    else {
+      if (d2 < 0)
+        d2 = 0;
+      if (d2 > len - d)
+        d2 = len - d;
+    }
+    result = String(s.substr(static_cast<int>(d), static_cast<int>(d2)));
     break;
   }
   case Substring: {
diff --git a/JavaScriptCore/kjs/value.cpp b/JavaScriptCore/kjs/value.cpp
index 5e0cf99..a2fb5cf 100644
--- a/JavaScriptCore/kjs/value.cpp
+++ b/JavaScriptCore/kjs/value.cpp
@@ -93,51 +93,65 @@ bool ValueImp::toUInt32(unsigned&) const
 }
 
 // ECMA 9.4
-int ValueImp::toInteger(ExecState *exec) const
+double ValueImp::toInteger(ExecState *exec) const
 {
-  unsigned i;
+  uint32_t i;
   if (dispatchToUInt32(i))
-    return (int)i;
-  return int(roundValue(exec, Value(const_cast<ValueImp*>(this))));
+    return i;
+  return roundValue(exec, Value(const_cast<ValueImp*>(this)));
 }
 
-int ValueImp::toInt32(ExecState *exec) const
+int32_t ValueImp::toInt32(ExecState *exec) const
 {
-  unsigned i;
+  uint32_t i;
   if (dispatchToUInt32(i))
-    return (int)i;
+    return i;
 
   double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
+  if (isNaN(d) || isInf(d))
+    return 0;
   double d32 = fmod(d, D32);
 
   if (d32 >= D32 / 2.0)
     d32 -= D32;
+  else if (d32 < -D32 / 2.0)
+    d32 += D32;
 
-  return static_cast<int>(d32);
+  return static_cast<int32_t>(d32);
 }
 
-unsigned int ValueImp::toUInt32(ExecState *exec) const
+uint32_t ValueImp::toUInt32(ExecState *exec) const
 {
-  unsigned i;
+  uint32_t i;
   if (dispatchToUInt32(i))
     return i;
 
   double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
+  if (isNaN(d) || isInf(d))
+    return 0;
   double d32 = fmod(d, D32);
 
-  return static_cast<unsigned int>(d32);
+  if (d32 < 0)
+    d32 += D32;
+
+  return static_cast<uint32_t>(d32);
 }
 
-unsigned short ValueImp::toUInt16(ExecState *exec) const
+uint16_t ValueImp::toUInt16(ExecState *exec) const
 {
-  unsigned i;
+  uint32_t i;
   if (dispatchToUInt32(i))
-    return (unsigned short)i;
+    return i;
 
   double d = roundValue(exec, Value(const_cast<ValueImp*>(this)));
+  if (isNaN(d) || isInf(d))
+    return 0;
   double d16 = fmod(d, D16);
 
-  return static_cast<unsigned short>(d16);
+  if (d16 < 0)
+    d16 += D16;
+
+  return static_cast<uint16_t>(d16);
 }
 
 // Dispatchers for virtual functions, to special-case simple numbers which
@@ -185,13 +199,13 @@ Object ValueImp::dispatchToObject(ExecState *exec) const
   return toObject(exec);
 }
 
-bool ValueImp::dispatchToUInt32(unsigned& result) const
+bool ValueImp::dispatchToUInt32(uint32_t& result) const
 {
   if (SimpleNumber::is(this)) {
     long i = SimpleNumber::value(this);
     if (i < 0)
       return false;
-    result = (unsigned)i;
+    result = i;
     return true;
   }
   return toUInt32(result);
diff --git a/JavaScriptCore/kjs/value.h b/JavaScriptCore/kjs/value.h
index 4312b2a..9fde98f 100644
--- a/JavaScriptCore/kjs/value.h
+++ b/JavaScriptCore/kjs/value.h
@@ -113,10 +113,10 @@ namespace KJS {
     // Will crash if called on a simple number.
     void setGcAllowedFast() { _flags |= VI_GCALLOWED; }
 
-    int toInteger(ExecState *exec) const;
-    int toInt32(ExecState *exec) const;
-    unsigned int toUInt32(ExecState *exec) const;
-    unsigned short toUInt16(ExecState *exec) const;
+    double toInteger(ExecState *exec) const;
+    int32_t toInt32(ExecState *exec) const;
+    uint32_t toUInt32(ExecState *exec) const;
+    uint16_t toUInt16(ExecState *exec) const;
 
     // Dispatch wrappers that handle the special small number case
 
@@ -125,7 +125,7 @@ namespace KJS {
     bool dispatchToBoolean(ExecState *exec) const;
     double dispatchToNumber(ExecState *exec) const;
     UString dispatchToString(ExecState *exec) const;
-    bool dispatchToUInt32(unsigned&) const;
+    bool dispatchToUInt32(uint32_t&) const;
     Object dispatchToObject(ExecState *exec) const;
 
     unsigned short int refcount;
@@ -218,22 +218,22 @@ namespace KJS {
     /**
      * Performs the ToInteger type conversion operation on this value (ECMA 9.4)
      */
-    int toInteger(ExecState *exec) const { return rep->toInteger(exec); }
+    double toInteger(ExecState *exec) const { return rep->toInteger(exec); }
 
     /**
      * Performs the ToInt32 type conversion operation on this value (ECMA 9.5)
      */
-    int toInt32(ExecState *exec) const { return rep->toInt32(exec); }
+    int32_t toInt32(ExecState *exec) const { return rep->toInt32(exec); }
 
     /**
      * Performs the ToUint32 type conversion operation on this value (ECMA 9.6)
      */
-    unsigned int toUInt32(ExecState *exec) const { return rep->toUInt32(exec); }
+    uint32_t toUInt32(ExecState *exec) const { return rep->toUInt32(exec); }
 
     /**
      * Performs the ToUint16 type conversion operation on this value (ECMA 9.7)
      */
-    unsigned short toUInt16(ExecState *exec) const { return rep->toUInt16(exec); }
+    uint16_t toUInt16(ExecState *exec) const { return rep->toUInt16(exec); }
 
     /**
      * Performs the ToString type conversion operation on this value (ECMA 9.8)
@@ -248,7 +248,7 @@ namespace KJS {
     /**
      * Checks if we can do a lossless conversion to UInt32.
      */
-    bool toUInt32(unsigned& i) const { return rep->dispatchToUInt32(i); }
+    bool toUInt32(uint32_t& i) const { return rep->dispatchToUInt32(i); }
 
   protected:
     ValueImp *rep;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list