]> granicus.if.org Git - icu/commitdiff
ICU-13158 avoid undefined double->int cast for ccc=value, range check before cast
authorMarkus Scherer <markus.icu@gmail.com>
Fri, 11 Aug 2017 18:54:53 +0000 (18:54 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Fri, 11 Aug 2017 18:54:53 +0000 (18:54 +0000)
X-SVN-Rev: 40325

icu4c/source/common/uniset_props.cpp
icu4c/source/test/intltest/usettest.cpp
icu4c/source/test/intltest/usettest.h

index 0a13740840b2b5fc98ac03546525996c4622ccc3..f87be3d2ed9d2d767d59c926a60bd0646f42886d 100644 (file)
@@ -1009,9 +1009,10 @@ UnicodeSet::applyPropertyAlias(const UnicodeString& prop,
                     p == UCHAR_LEAD_CANONICAL_COMBINING_CLASS) {
                     char* end;
                     double value = uprv_strtod(vname.data(), &end);
-                    v = (int32_t) value;
-                    if (v != value || v < 0 || *end != 0) {
-                        // non-integral or negative value, or trailing junk
+                    // Cast double->int only after range check.
+                    if (*end != 0 || value < 0 || 255 < value ||
+                            (v = (int32_t)value) != value) {
+                        // non-integral value or outside 0..255, or trailing junk
                         FAIL(ec);
                     }
                     // If the resultant set is empty then the numeric value
index 40851176fb8e7e8b1d3312f23e69e2ee47d9c437..ed6419a0ebde476ee53f2465745d665410759af4 100644 (file)
@@ -67,35 +67,37 @@ UnicodeSetTest::~UnicodeSetTest() {
 void
 UnicodeSetTest::runIndexedTest(int32_t index, UBool exec,
                                const char* &name, char* /*par*/) {
-    // if (exec) logln((UnicodeString)"TestSuite UnicodeSetTest");
-    switch (index) {
-        CASE(0,TestPatterns);
-        CASE(1,TestAddRemove);
-        CASE(2,TestCategories);
-        CASE(3,TestCloneEqualHash);
-        CASE(4,TestMinimalRep);
-        CASE(5,TestAPI);
-        CASE(6,TestScriptSet);
-        CASE(7,TestPropertySet);
-        CASE(8,TestClone);
-        CASE(9,TestExhaustive);
-        CASE(10,TestToPattern);
-        CASE(11,TestIndexOf);
-        CASE(12,TestStrings);
-        CASE(13,Testj2268);
-        CASE(14,TestCloseOver);
-        CASE(15,TestEscapePattern);
-        CASE(16,TestInvalidCodePoint);
-        CASE(17,TestSymbolTable);
-        CASE(18,TestSurrogate);
-        CASE(19,TestPosixClasses);
-        CASE(20,TestIteration);
-        CASE(21,TestFreezable);
-        CASE(22,TestSpan);
-        CASE(23,TestStringSpan);
-        CASE(24,TestUCAUnsafeBackwards);
-        default: name = ""; break;
-    }
+    if (exec) {
+        logln(u"TestSuite UnicodeSetTest");
+    }
+    TESTCASE_AUTO_BEGIN;
+    TESTCASE_AUTO(TestPatterns);
+    TESTCASE_AUTO(TestAddRemove);
+    TESTCASE_AUTO(TestCategories);
+    TESTCASE_AUTO(TestCloneEqualHash);
+    TESTCASE_AUTO(TestMinimalRep);
+    TESTCASE_AUTO(TestAPI);
+    TESTCASE_AUTO(TestScriptSet);
+    TESTCASE_AUTO(TestPropertySet);
+    TESTCASE_AUTO(TestClone);
+    TESTCASE_AUTO(TestExhaustive);
+    TESTCASE_AUTO(TestToPattern);
+    TESTCASE_AUTO(TestIndexOf);
+    TESTCASE_AUTO(TestStrings);
+    TESTCASE_AUTO(Testj2268);
+    TESTCASE_AUTO(TestCloseOver);
+    TESTCASE_AUTO(TestEscapePattern);
+    TESTCASE_AUTO(TestInvalidCodePoint);
+    TESTCASE_AUTO(TestSymbolTable);
+    TESTCASE_AUTO(TestSurrogate);
+    TESTCASE_AUTO(TestPosixClasses);
+    TESTCASE_AUTO(TestIteration);
+    TESTCASE_AUTO(TestFreezable);
+    TESTCASE_AUTO(TestSpan);
+    TESTCASE_AUTO(TestStringSpan);
+    TESTCASE_AUTO(TestUCAUnsafeBackwards);
+    TESTCASE_AUTO(TestIntOverflow);
+    TESTCASE_AUTO_END;
 }
 
 static const char NOT[] = "%%%%";
@@ -3925,3 +3927,12 @@ void UnicodeSetTest::TestUCAUnsafeBackwards() {
     }
 #endif
 }
+
+void UnicodeSetTest::TestIntOverflow() {
+    // This test triggers undefined double->int conversion behavior
+    // if the implementation is not careful.
+    IcuTestErrorCode errorCode(*this, "TestIntOverflow");
+    UnicodeSet set(u"[:ccc=2222222222222222222:]", errorCode);
+    assertTrue("[:ccc=int_overflow:] -> empty set", set.isEmpty());
+    assertEquals("[:ccc=int_overflow:] -> illegal argument", U_ILLEGAL_ARGUMENT_ERROR, errorCode.reset());
+}
index 45c6dfd20fa4a50a9dc458527066fd3823988b4c..f0fe250114f3ec28d71c9dc4e80b035cb7883d12 100644 (file)
@@ -91,6 +91,7 @@ private:
     void TestStringSpan();
 
     void TestUCAUnsafeBackwards();
+    void TestIntOverflow();
 
 private: