[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

simon.fraser at apple.com simon.fraser at apple.com
Wed Dec 22 14:48:51 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit a737901fbf881d7ee24c579d22e170a90418b038
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 21 01:15:07 2010 +0000

    2010-10-19  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Gavin Barraclough.
    
            https://bugs.webkit.org/show_bug.cgi?id=47851
    
            Add methods to DecimalNumber to return the buffer length
            required for decimal and exponential output.
    
            Make some of the DecimalNumber code non-inline (no
            effect on Sunspider), adding DecimalNumber.cpp to various
            build systems.
    
            Make some DecimalNumber methods 'const'.
    
            * Android.mk:
            * Android.v8.wtf.mk:
            * GNUmakefile.am:
            * JavaScriptCore.exp:
            * JavaScriptCore.gypi:
            * JavaScriptCore.vcproj/WTF/WTF.vcproj:
            * JavaScriptCore.xcodeproj/project.pbxproj:
            * runtime/NumberPrototype.cpp:
            (JSC::numberProtoFuncToExponential):
            (JSC::numberProtoFuncToFixed):
            (JSC::numberProtoFuncToPrecision):
            * wtf/DecimalNumber.cpp: Added.
            (WTF::DecimalNumber::bufferLengthForStringDecimal):
            (WTF::DecimalNumber::bufferLengthForStringExponential):
            (WTF::DecimalNumber::toStringDecimal):
            (WTF::DecimalNumber::toStringExponential):
            * wtf/DecimalNumber.h:
            (WTF::DecimalNumber::sign):
            (WTF::DecimalNumber::exponent):
            (WTF::DecimalNumber::significand):
            (WTF::DecimalNumber::precision):
            * wtf/dtoa.cpp:
            (WTF::dtoa):
            * wtf/dtoa.h:
            * wtf/wtf.pri:
    
    2010-10-19  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Gavin Barraclough.
    
            https://bugs.webkit.org/show_bug.cgi?id=47851
    
            Avoid buffer overflows in CSSPrimitiveValue's use of
            DecimalNumber, and pass the buffer size in InspectorBasicValue.
    
            Test: fast/css/large-value-csstext.html
    
            * css/CSSPrimitiveValue.cpp:
            (WebCore::formatNumber):
            * inspector/InspectorValues.cpp:
            (WebCore::InspectorBasicValue::writeJSON):
    
    2010-10-20  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Gavin Barraclough.
    
            https://bugs.webkit.org/show_bug.cgi?id=47851
    
            Fix buffer overflow in the printing of very large and very small numbers in
            CSSPrimitiveValues.
    
            * fast/css/large-value-csstext-expected.txt: Added.
            * fast/css/large-value-csstext.html: Added.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70198 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk
index 932ebc0..e52922f 100644
--- a/JavaScriptCore/Android.mk
+++ b/JavaScriptCore/Android.mk
@@ -158,6 +158,7 @@ LOCAL_SRC_FILES := \
 	wtf/ByteArray.cpp \
 	wtf/CurrentTime.cpp \
 	wtf/DateMath.cpp \
+	wtf/DecimalNumber.cpp \
 	wtf/FastMalloc.cpp \
 	wtf/HashTable.cpp \
 	wtf/MainThread.cpp \
diff --git a/JavaScriptCore/Android.v8.wtf.mk b/JavaScriptCore/Android.v8.wtf.mk
index cb5039b..17e2816 100644
--- a/JavaScriptCore/Android.v8.wtf.mk
+++ b/JavaScriptCore/Android.v8.wtf.mk
@@ -36,6 +36,7 @@ LOCAL_SRC_FILES := \
 	wtf/ByteArray.cpp \
 	wtf/CurrentTime.cpp \
 	wtf/DateMath.cpp \
+	wtf/DecimalNumber.cpp \
 	wtf/FastMalloc.cpp \
 	wtf/HashTable.cpp \
 	wtf/MainThread.cpp \
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 3dd21c3..7773d7c 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,44 @@
+2010-10-19  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        https://bugs.webkit.org/show_bug.cgi?id=47851
+        
+        Add methods to DecimalNumber to return the buffer length
+        required for decimal and exponential output.
+        
+        Make some of the DecimalNumber code non-inline (no
+        effect on Sunspider), adding DecimalNumber.cpp to various
+        build systems.
+        
+        Make some DecimalNumber methods 'const'.
+
+        * Android.mk:
+        * Android.v8.wtf.mk:
+        * GNUmakefile.am:
+        * JavaScriptCore.exp:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/NumberPrototype.cpp:
+        (JSC::numberProtoFuncToExponential):
+        (JSC::numberProtoFuncToFixed):
+        (JSC::numberProtoFuncToPrecision):
+        * wtf/DecimalNumber.cpp: Added.
+        (WTF::DecimalNumber::bufferLengthForStringDecimal):
+        (WTF::DecimalNumber::bufferLengthForStringExponential):
+        (WTF::DecimalNumber::toStringDecimal):
+        (WTF::DecimalNumber::toStringExponential):
+        * wtf/DecimalNumber.h:
+        (WTF::DecimalNumber::sign):
+        (WTF::DecimalNumber::exponent):
+        (WTF::DecimalNumber::significand):
+        (WTF::DecimalNumber::precision):
+        * wtf/dtoa.cpp:
+        (WTF::dtoa):
+        * wtf/dtoa.h:
+        * wtf/wtf.pri:
+
 2010-10-20  Sheriff Bot  <webkit.review.bot at gmail.com>
 
         Unreviewed, rolling out r70165.
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 7ee368a..c507f5d 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -430,6 +430,7 @@ javascriptcore_sources += \
 	JavaScriptCore/wtf/DateMath.cpp \
 	JavaScriptCore/wtf/DateMath.h \
 	JavaScriptCore/wtf/DecimalNumber.h \
+	JavaScriptCore/wtf/DecimalNumber.cpp \
 	JavaScriptCore/wtf/Deque.h \
 	JavaScriptCore/wtf/DisallowCType.h \
 	JavaScriptCore/wtf/dtoa.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 8f3ed5d..6ef8ead 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -549,6 +549,8 @@ __ZN3WTF11dtoaRoundSFEPcdiRbRiRj
 __ZN3WTF11dtoaRoundDPEPcdiRbRiRj
 __ZN3WTF4dtoaEPcdRbRiRj
 __ZNK3WTF12AtomicString5lowerEv
+__ZNK3WTF13DecimalNumber15toStringDecimalEPtj
+__ZNK3WTF13DecimalNumber28bufferLengthForStringDecimalEv
 __ZNK3WTF6String11toIntStrictEPbi
 __ZNK3WTF6String12toUIntStrictEPbi
 __ZNK3WTF6String13toInt64StrictEPbi
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index 1190a96..6252d07 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -365,6 +365,7 @@
             'wtf/CurrentTime.h',
             'wtf/DateMath.cpp',
             'wtf/DateMath.h',
+            'wtf/DecimalNumber.cpp',
             'wtf/Deque.h',
             'wtf/DisallowCType.h',
             'wtf/dtoa.cpp',
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 1fde6f4..3a53070 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -309,6 +309,14 @@
 			>
 		</File>
 		<File
+			RelativePath="..\..\wtf\DecimalNumber.cpp"
+			>
+		</File>
+		<File
+			RelativePath="..\..\wtf\DecimalNumber.h"
+			>
+		</File>
+		<File
 			RelativePath="..\..\wtf\FastAllocBase.h"
 			>
 		</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 45628a9..d134a73 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -47,6 +47,7 @@
 		0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
+		0F29479C126E698C00B3ABF5 /* DecimalNumber.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */; };
 		14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
 		140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */; };
@@ -646,6 +647,7 @@
 		0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnFastMallocPtr.h; sourceTree = "<group>"; };
 		0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadRefCounted.h; sourceTree = "<group>"; };
 		0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
+		0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DecimalNumber.cpp; sourceTree = "<group>"; };
 		14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCPtr.h; sourceTree = "<group>"; };
 		140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; };
 		141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; };
@@ -1488,6 +1490,7 @@
 				41359CF40FDD89CB00206180 /* DateMath.cpp */,
 				41359CF50FDD89CB00206180 /* DateMath.h */,
 				862AF4B512239C7B0024E5B8 /* DecimalNumber.h */,
+				0F29479B126E698C00B3ABF5 /* DecimalNumber.cpp */,
 				5186111D0CC824830081412B /* Deque.h */,
 				938C4F6B0CA06BCE00D9310A /* DisallowCType.h */,
 				651F6412039D5B5F0078395C /* dtoa.cpp */,
@@ -2803,6 +2806,7 @@
 				90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */,
 				A730B6131250068F009D25B1 /* StrictEvalActivation.cpp in Sources */,
 				86438FC41265503E00E0DFCA /* StringBuilder.cpp in Sources */,
+				0F29479C126E698C00B3ABF5 /* DecimalNumber.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index df8ac4c..4a2ca74 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -117,8 +117,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
     // Round if the argument is not undefined, always format as exponential.
     NumberToStringBuffer buffer;
     unsigned length = isUndefined
-        ? DecimalNumber(x).toStringExponential(buffer)
-        : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer);
+        ? DecimalNumber(x).toStringExponential(buffer, WTF::NumberToStringBufferLength)
+        : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer, WTF::NumberToStringBufferLength);
 
     return JSValue::encode(jsString(exec, UString(buffer, length)));
 }
@@ -154,7 +154,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
 
     // Convert to decimal with rounding, and format as decimal.
     NumberToStringBuffer buffer;
-    unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer);
+    unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer, WTF::NumberToStringBufferLength);
     return JSValue::encode(jsString(exec, UString(buffer, length)));
 }
 
@@ -196,8 +196,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
     // 1234 (1.234e+3) requires 4 digits. (See ECMA-262 15.7.4.7.10.c)
     NumberToStringBuffer buffer;
     unsigned length = number.exponent() >= -6 && number.exponent() < significantFigures
-        ? number.toStringDecimal(buffer)
-        : number.toStringExponential(buffer);
+        ? number.toStringDecimal(buffer, WTF::NumberToStringBufferLength)
+        : number.toStringExponential(buffer, WTF::NumberToStringBufferLength);
     return JSValue::encode(jsString(exec, UString(buffer, length)));
 }
 
diff --git a/JavaScriptCore/wtf/DecimalNumber.cpp b/JavaScriptCore/wtf/DecimalNumber.cpp
new file mode 100644
index 0000000..70304e2
--- /dev/null
+++ b/JavaScriptCore/wtf/DecimalNumber.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DecimalNumber.h"
+#include <math.h>
+#include <wtf/MathExtras.h>
+#include <wtf/text/WTFString.h>
+
+namespace WTF {
+
+unsigned DecimalNumber::bufferLengthForStringDecimal() const
+{
+    unsigned length = 0;
+    // if the exponent is negative the number decimal representation is of the form:
+    // [<sign>]0.[<zeros>]<significand>
+    if (m_exponent < 0) {
+        if (m_sign)
+            ++length;
+        length += 2; // for "0."
+        length += -m_exponent - 1;
+        length += m_precision;
+        return length;
+    }
+
+    unsigned digitsBeforeDecimalPoint = m_exponent + 1;
+
+    // If the precision is <= than the number of digits to get up to the decimal
+    // point, then there is no fractional part, number is of the form:
+    // [<sign>]<significand>[<zeros>]
+    if (m_precision <= digitsBeforeDecimalPoint) {
+        if (m_sign)
+            ++length;
+        length += m_precision;
+        length += digitsBeforeDecimalPoint - m_precision;
+        return length;
+    }
+
+    // If we get here, number starts before the decimal point, and ends after it,
+    // as such is of the form:
+    // [<sign>]<significand-begin>.<significand-end>
+    if (m_sign)
+        ++length;
+    length += digitsBeforeDecimalPoint;
+    ++length; // for decimal point
+    length += m_precision - digitsBeforeDecimalPoint;
+
+    return length;
+}
+
+unsigned DecimalNumber::bufferLengthForStringExponential() const
+{
+    unsigned length = 0;
+    if (m_sign)
+        ++length;
+
+    // Add the significand
+    ++length;
+
+    if (m_precision > 1) {
+        ++length; // for decimal point
+        length += m_precision - 1;
+    }
+
+    // Add "e+" or "e-"
+    length += 2;
+
+    int exponent = (m_exponent >= 0) ? m_exponent : -m_exponent;
+
+    // Add the exponent
+    if (exponent >= 100)
+        ++length;
+    if (exponent >= 10)
+        ++length;
+    ++length;
+
+    return length;
+}
+
+unsigned DecimalNumber::toStringDecimal(UChar* buffer, unsigned bufferLength) const
+{
+    ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringDecimal());
+
+    // Should always be at least one digit to add to the string!
+    ASSERT(m_precision);
+    UChar* next = buffer;
+
+    // if the exponent is negative the number decimal representation is of the form:
+    // [<sign>]0.[<zeros>]<significand>
+    if (m_exponent < 0) {
+        unsigned zeros = -m_exponent - 1;
+
+        if (m_sign)
+            *next++ = '-';
+        *next++ = '0';
+        *next++ = '.';
+        for (unsigned i = 0; i < zeros; ++i)
+            *next++ = '0';
+        for (unsigned i = 0; i < m_precision; ++i)
+            *next++ = m_significand[i];
+
+        return next - buffer;
+    }
+
+    unsigned digitsBeforeDecimalPoint = m_exponent + 1;
+
+    // If the precision is <= than the number of digits to get up to the decimal
+    // point, then there is no fractional part, number is of the form:
+    // [<sign>]<significand>[<zeros>]
+    if (m_precision <= digitsBeforeDecimalPoint) {
+        if (m_sign)
+            *next++ = '-';
+        for (unsigned i = 0; i < m_precision; ++i)
+            *next++ = m_significand[i];
+        for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i)
+            *next++ = '0';
+
+        return next - buffer;
+    }
+
+    // If we get here, number starts before the decimal point, and ends after it,
+    // as such is of the form:
+    // [<sign>]<significand-begin>.<significand-end>
+
+    if (m_sign)
+        *next++ = '-';
+    for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i)
+        *next++ = m_significand[i];
+    *next++ = '.';
+    for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i)
+        *next++ = m_significand[i];
+
+    return next - buffer;
+}
+
+unsigned DecimalNumber::toStringExponential(UChar* buffer, unsigned bufferLength) const
+{
+    ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringExponential());
+
+    // Should always be at least one digit to add to the string!
+    ASSERT(m_precision);
+    UChar* next = buffer;
+
+    // Add the sign
+    if (m_sign)
+        *next++ = '-';
+
+    // Add the significand
+    *next++ = m_significand[0];
+    if (m_precision > 1) {
+        *next++ = '.';
+        for (unsigned i = 1; i < m_precision; ++i)
+            *next++ = m_significand[i];
+    }
+
+    // Add "e+" or "e-"
+    *next++ = 'e';
+    int exponent;
+    if (m_exponent >= 0) {
+        *next++ = '+';
+        exponent = m_exponent;
+    } else {
+        *next++ = '-';
+        exponent = -m_exponent;
+    }
+
+    // Add the exponent
+    if (exponent >= 100)
+        *next++ = '0' + exponent / 100;
+    if (exponent >= 10)
+        *next++ = '0' + (exponent % 100) / 10;
+    *next++ = '0' + exponent % 10;
+
+    return next - buffer;
+}
+
+} // namespace WTF
diff --git a/JavaScriptCore/wtf/DecimalNumber.h b/JavaScriptCore/wtf/DecimalNumber.h
index 3a831b7..c42f00b 100644
--- a/JavaScriptCore/wtf/DecimalNumber.h
+++ b/JavaScriptCore/wtf/DecimalNumber.h
@@ -81,104 +81,16 @@ public:
         ASSERT(m_significand[0] != '0' || !m_exponent);
     }
 
-    unsigned toStringDecimal(NumberToStringBuffer buffer)
-    {
-        // Should always be at least one digit to add to the string!
-        ASSERT(m_precision);
-        UChar* next = buffer;
-
-        // if the exponent is negative the number decimal representation is of the form:
-        // [<sign>]0.[<zeros>]<significand>
-        if (m_exponent < 0) {
-            unsigned zeros = -m_exponent - 1;
-
-            if (m_sign)
-                *next++ = '-';
-            *next++ = '0';
-            *next++ = '.';
-            for (unsigned i = 0; i < zeros; ++i)
-                *next++ = '0';
-            for (unsigned i = 0; i < m_precision; ++i)
-                *next++ = m_significand[i];
-
-            return next - buffer;
-        }
-
-        unsigned digitsBeforeDecimalPoint = m_exponent + 1;
-
-        // If the precision is <= than the number of digits to get up to the decimal
-        // point, then there is no fractional part, number is of the form:
-        // [<sign>]<significand>[<zeros>]
-        if (m_precision <= digitsBeforeDecimalPoint) {
-            if (m_sign)
-                *next++ = '-';
-            for (unsigned i = 0; i < m_precision; ++i)
-                *next++ = m_significand[i];
-            for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i)
-                *next++ = '0';
-
-            return next - buffer;
-        }
-
-        // If we get here, number starts before the decimal point, and ends after it,
-        // as such is of the form:
-        // [<sign>]<significand-begin>.<significand-end>
-
-        if (m_sign)
-            *next++ = '-';
-        for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i)
-            *next++ = m_significand[i];
-        *next++ = '.';
-        for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i)
-            *next++ = m_significand[i];
-
-        return next - buffer;
-    }
+    unsigned bufferLengthForStringDecimal() const;
+    unsigned bufferLengthForStringExponential() const;
 
-    unsigned toStringExponential(NumberToStringBuffer buffer)
-    {
-        // Should always be at least one digit to add to the string!
-        ASSERT(m_precision);
-
-        UChar* next = buffer;
-
-        // Add the sign
-        if (m_sign)
-            *next++ = '-';
-
-        // Add the significand
-        *next++ = m_significand[0];
-        if (m_precision > 1) {
-            *next++ = '.';
-            for (unsigned i = 1; i < m_precision; ++i)
-                *next++ = m_significand[i];
-        }
-
-        // Add "e+" or "e-"
-        *next++ = 'e';
-        int exponent;
-        if (m_exponent >= 0) {
-            *next++ = '+';
-            exponent = m_exponent;
-        } else {
-            *next++ = '-';
-            exponent = -m_exponent;
-        }
-
-        // Add the exponent
-        if (exponent >= 100)
-            *next++ = '0' + exponent / 100;
-        if (exponent >= 10)
-            *next++ = '0' + (exponent % 100) / 10;
-        *next++ = '0' + exponent % 10;
-
-        return next - buffer;
-    }
+    unsigned toStringDecimal(UChar* buffer, unsigned bufferLength) const;
+    unsigned toStringExponential(UChar* buffer, unsigned bufferLength) const;
 
-    bool sign() { return m_sign; }
-    int exponent() { return m_exponent; }
-    const char* significand() { return m_significand; } // significand contains precision characters, is not null-terminated.
-    unsigned precision() { return m_precision; }
+    bool sign() const { return m_sign; }
+    int exponent() const { return m_exponent; }
+    const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
+    unsigned precision() const { return m_precision; }
 
 private:
     bool m_sign;
diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp
index 298bb27..c89c036 100644
--- a/JavaScriptCore/wtf/dtoa.cpp
+++ b/JavaScriptCore/wtf/dtoa.cpp
@@ -1824,8 +1824,8 @@ unsigned numberToString(double d, NumberToStringBuffer buffer)
     // Convert to decimal with rounding.
     DecimalNumber number(d);
     return number.exponent() >= -6 && number.exponent() < 21
-        ? number.toStringDecimal(buffer)
-        : number.toStringExponential(buffer);
+        ? number.toStringDecimal(buffer, NumberToStringBufferLength)
+        : number.toStringExponential(buffer, NumberToStringBufferLength);
 }
 
 } // namespace WTF
diff --git a/JavaScriptCore/wtf/dtoa.h b/JavaScriptCore/wtf/dtoa.h
index 7e4fc41..3924a1c 100644
--- a/JavaScriptCore/wtf/dtoa.h
+++ b/JavaScriptCore/wtf/dtoa.h
@@ -39,7 +39,8 @@ void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exp
 void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision);
 
 // Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits.
-typedef UChar NumberToStringBuffer[96];
+const unsigned NumberToStringBufferLength = 96;
+typedef UChar NumberToStringBuffer[NumberToStringBufferLength];
 unsigned numberToString(double, NumberToStringBuffer);
 
 } // namespace WTF
diff --git a/JavaScriptCore/wtf/wtf.pri b/JavaScriptCore/wtf/wtf.pri
index b176481..83e71d8 100644
--- a/JavaScriptCore/wtf/wtf.pri
+++ b/JavaScriptCore/wtf/wtf.pri
@@ -6,6 +6,7 @@ SOURCES += \
     wtf/CurrentTime.cpp \
     wtf/DateMath.cpp \
     wtf/dtoa.cpp \
+    wtf/DecimalNumber.cpp \
     wtf/FastMalloc.cpp \
     wtf/HashTable.cpp \
     wtf/MD5.cpp \
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 043e5d7..d97d78f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2010-10-20  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        https://bugs.webkit.org/show_bug.cgi?id=47851
+        
+        Fix buffer overflow in the printing of very large and very small numbers in
+        CSSPrimitiveValues.
+
+        * fast/css/large-value-csstext-expected.txt: Added.
+        * fast/css/large-value-csstext.html: Added.
+
 2010-10-20  Beth Dakin  <bdakin at apple.com>
 
         Reviewed by Simon Fraser.
diff --git a/LayoutTests/fast/css/large-value-csstext-expected.txt b/LayoutTests/fast/css/large-value-csstext-expected.txt
new file mode 100644
index 0000000..2b8804d
--- /dev/null
+++ b/LayoutTests/fast/css/large-value-csstext-expected.txt
@@ -0,0 +1,4 @@
+This test should not crash.
+
+100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000% 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%
+0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009% 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009%
diff --git a/LayoutTests/fast/css/large-value-csstext.html b/LayoutTests/fast/css/large-value-csstext.html
new file mode 100644
index 0000000..8e59eee
--- /dev/null
+++ b/LayoutTests/fast/css/large-value-csstext.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style type="text/css" media="screen">
+        #box {
+            border-top-left-radius:  99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999%;
+            border-top-right-radius: 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009%;
+        }
+    </style>
+    <script type="text/javascript" charset="utf-8">
+      if (window.layoutTestController)
+        layoutTestController.dumpAsText();
+    </script>
+</head>
+<body>
+  <p>This test should not crash.</p>
+  <div id="box"></div>
+  <div id="output"></div>
+  <script type="text/javascript" charset="utf-8">
+    var output = document.getElementById('output');
+
+    var rule = document.styleSheets[0].cssRules[0];
+    output.innerHTML += rule.style.getPropertyCSSValue('border-top-left-radius').cssText + "<br>";
+    output.innerHTML += rule.style.getPropertyCSSValue('border-top-right-radius').cssText;
+  </script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4542627..4687e24 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2010-10-19  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Gavin Barraclough.
+
+        https://bugs.webkit.org/show_bug.cgi?id=47851
+        
+        Avoid buffer overflows in CSSPrimitiveValue's use of 
+        DecimalNumber, and pass the buffer size in InspectorBasicValue.
+
+        Test: fast/css/large-value-csstext.html
+
+        * css/CSSPrimitiveValue.cpp:
+        (WebCore::formatNumber):
+        * inspector/InspectorValues.cpp:
+        (WebCore::InspectorBasicValue::writeJSON):
+
 2010-10-20  Dumitru Daniliuc  <dumi at chromium.org>
 
         Reviewed by David Levin.
diff --git a/WebCore/css/CSSPrimitiveValue.cpp b/WebCore/css/CSSPrimitiveValue.cpp
index 24f2451..065c244 100644
--- a/WebCore/css/CSSPrimitiveValue.cpp
+++ b/WebCore/css/CSSPrimitiveValue.cpp
@@ -37,6 +37,7 @@
 #include <wtf/ASCIICType.h>
 #include <wtf/DecimalNumber.h>
 #include <wtf/StdLibExtras.h>
+#include <wtf/text/StringBuffer.h>
 
 #if ENABLE(DASHBOARD_SUPPORT)
 #include "DashboardRegion.h"
@@ -616,9 +617,13 @@ int CSSPrimitiveValue::getIdent()
 
 static String formatNumber(double number)
 {
-    NumberToStringBuffer buffer;
-    unsigned length = DecimalNumber(number).toStringDecimal(buffer);
-    return String(buffer, length);
+    DecimalNumber decimal(number);
+    
+    StringBuffer buffer(decimal.bufferLengthForStringDecimal());
+    unsigned length = decimal.toStringDecimal(buffer.characters(), buffer.length());
+    ASSERT_UNUSED(length, length == buffer.length());
+
+    return String::adopt(buffer);
 }
 
 String CSSPrimitiveValue::cssText() const
diff --git a/WebCore/inspector/InspectorValues.cpp b/WebCore/inspector/InspectorValues.cpp
index 318d7bb..89e9b7c 100644
--- a/WebCore/inspector/InspectorValues.cpp
+++ b/WebCore/inspector/InspectorValues.cpp
@@ -607,7 +607,7 @@ void InspectorBasicValue::writeJSON(Vector<UChar>* output) const
             output->append(falseString, 5);
     } else if (type() == TypeNumber) {
         NumberToStringBuffer buffer;
-        unsigned length = DecimalNumber(m_doubleValue).toStringDecimal(buffer);
+        unsigned length = DecimalNumber(m_doubleValue).toStringDecimal(buffer, WTF::NumberToStringBufferLength);
         output->append(buffer, length);
     }
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list