mirror of
https://abf.rosa.ru/djam/icu.git
synced 2025-02-23 19:02:50 +00:00

1.CVE-2016-6293 2.CVE-2016-7415 3.CVE-2017-7867 4.CVE-2017-7868 5.CVE-2017-14952 6.CVE-2017-15422 7.CVE-2020-10531
118 lines
4.9 KiB
Diff
118 lines
4.9 KiB
Diff
Index: icu4c/source/i18n/gregoimp.cpp
|
|
===================================================================
|
|
--- icu4c/source/i18n/gregoimp.cpp (revision 40653)
|
|
+++ icu4c/source/i18n/gregoimp.cpp (revision 40654)
|
|
@@ -29,6 +29,11 @@ int32_t ClockMath::floorDivide(int32_t n
|
|
numerator / denominator : ((numerator + 1) / denominator) - 1;
|
|
}
|
|
|
|
+int64_t ClockMath::floorDivide(int64_t numerator, int64_t denominator) {
|
|
+ return (numerator >= 0) ?
|
|
+ numerator / denominator : ((numerator + 1) / denominator) - 1;
|
|
+}
|
|
+
|
|
int32_t ClockMath::floorDivide(double numerator, int32_t denominator,
|
|
int32_t& remainder) {
|
|
double quotient;
|
|
Index: icu4c/source/i18n/gregoimp.h
|
|
===================================================================
|
|
--- icu4c/source/i18n/gregoimp.h (revision 40653)
|
|
+++ icu4c/source/i18n/gregoimp.h (revision 40654)
|
|
@@ -39,6 +39,17 @@ class ClockMath {
|
|
static int32_t floorDivide(int32_t numerator, int32_t denominator);
|
|
|
|
/**
|
|
+ * Divide two integers, returning the floor of the quotient.
|
|
+ * Unlike the built-in division, this is mathematically
|
|
+ * well-behaved. E.g., <code>-1/4</code> => 0 but
|
|
+ * <code>floorDivide(-1,4)</code> => -1.
|
|
+ * @param numerator the numerator
|
|
+ * @param denominator a divisor which must be != 0
|
|
+ * @return the floor of the quotient
|
|
+ */
|
|
+ static int64_t floorDivide(int64_t numerator, int64_t denominator);
|
|
+
|
|
+ /**
|
|
* Divide two numbers, returning the floor of the quotient.
|
|
* Unlike the built-in division, this is mathematically
|
|
* well-behaved. E.g., <code>-1/4</code> => 0 but
|
|
Index: icu4c/source/i18n/persncal.cpp
|
|
===================================================================
|
|
--- icu4c/source/i18n/persncal.cpp (revision 40653)
|
|
+++ icu4c/source/i18n/persncal.cpp (revision 40654)
|
|
@@ -211,7 +211,7 @@ void PersianCalendar::handleComputeField
|
|
int32_t year, month, dayOfMonth, dayOfYear;
|
|
|
|
int32_t daysSinceEpoch = julianDay - PERSIAN_EPOCH;
|
|
- year = 1 + ClockMath::floorDivide(33 * daysSinceEpoch + 3, 12053);
|
|
+ year = 1 + (int32_t)ClockMath::floorDivide(33 * (int64_t)daysSinceEpoch + 3, (int64_t)12053);
|
|
|
|
int32_t farvardin1 = 365 * (year - 1) + ClockMath::floorDivide(8 * year + 21, 33);
|
|
dayOfYear = (daysSinceEpoch - farvardin1); // 0-based
|
|
Index: icu4c/source/test/intltest/calregts.cpp
|
|
===================================================================
|
|
--- icu4c/source/test/intltest/calregts.cpp (revision 40653)
|
|
+++ icu4c/source/test/intltest/calregts.cpp (revision 40654)
|
|
@@ -10,6 +10,7 @@
|
|
|
|
#include "calregts.h"
|
|
|
|
+#include "unicode/calendar.h"
|
|
#include "unicode/gregocal.h"
|
|
#include "unicode/simpletz.h"
|
|
#include "unicode/smpdtfmt.h"
|
|
@@ -88,6 +89,7 @@ CalendarRegressionTest::runIndexedTest(
|
|
CASE(48,TestT8596);
|
|
CASE(49,Test9019);
|
|
CASE(50,TestT9452);
|
|
+ CASE(51,TestPersianCalOverflow);
|
|
default: name = ""; break;
|
|
}
|
|
}
|
|
@@ -2944,4 +2946,34 @@ void CalendarRegressionTest::TestT9452(v
|
|
}
|
|
}
|
|
|
|
+/**
|
|
+ * @bug ticket 13454
|
|
+ */
|
|
+void CalendarRegressionTest::TestPersianCalOverflow(void) {
|
|
+ const char* localeID = "bs_Cyrl@calendar=persian";
|
|
+ UErrorCode status = U_ZERO_ERROR;
|
|
+ Calendar* cal = Calendar::createInstance(Locale(localeID), status);
|
|
+ if(U_FAILURE(status)) {
|
|
+ dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID, u_errorName(status));
|
|
+ } else {
|
|
+ int32_t maxMonth = cal->getMaximum(UCAL_MONTH);
|
|
+ int32_t maxDayOfMonth = cal->getMaximum(UCAL_DATE);
|
|
+ int32_t jd, month, dayOfMonth;
|
|
+ for (jd = 67023580; jd <= 67023584; jd++) { // year 178171, int32_t overflow if jd >= 67023582
|
|
+ status = U_ZERO_ERROR;
|
|
+ cal->clear();
|
|
+ cal->set(UCAL_JULIAN_DAY, jd);
|
|
+ month = cal->get(UCAL_MONTH, status);
|
|
+ dayOfMonth = cal->get(UCAL_DATE, status);
|
|
+ if ( U_FAILURE(status) ) {
|
|
+ errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s\n", localeID, jd, u_errorName(status));
|
|
+ } else if (month > maxMonth || dayOfMonth > maxDayOfMonth) {
|
|
+ errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d\n",
|
|
+ localeID, jd, maxMonth, month, maxDayOfMonth, dayOfMonth);
|
|
+ }
|
|
+ }
|
|
+ delete cal;
|
|
+ }
|
|
+}
|
|
+
|
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
Index: icu4c/source/test/intltest/calregts.h
|
|
===================================================================
|
|
--- icu4c/source/test/intltest/calregts.h (revision 40653)
|
|
+++ icu4c/source/test/intltest/calregts.h (revision 40654)
|
|
@@ -75,6 +75,7 @@ public:
|
|
void TestT8596(void);
|
|
void Test9019(void);
|
|
void TestT9452(void);
|
|
+ void TestPersianCalOverflow(void);
|
|
|
|
void printdate(GregorianCalendar *cal, const char *string);
|
|
void dowTest(UBool lenient) ;
|