[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