CVE-2017-15422.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. Index: source/i18n/gregoimp.cpp
  2. ===================================================================
  3. --- source/i18n/gregoimp.cpp (revision 40653)
  4. +++ source/i18n/gregoimp.cpp (revision 40654)
  5. @@ -24,4 +24,9 @@
  6. int32_t ClockMath::floorDivide(int32_t numerator, int32_t denominator) {
  7. + return (numerator >= 0) ?
  8. + numerator / denominator : ((numerator + 1) / denominator) - 1;
  9. +}
  10. +
  11. +int64_t ClockMath::floorDivide(int64_t numerator, int64_t denominator) {
  12. return (numerator >= 0) ?
  13. numerator / denominator : ((numerator + 1) / denominator) - 1;
  14. Index: source/i18n/gregoimp.h
  15. ===================================================================
  16. --- source/i18n/gregoimp.h (revision 40653)
  17. +++ source/i18n/gregoimp.h (revision 40654)
  18. @@ -40,4 +40,15 @@
  19. */
  20. static int32_t floorDivide(int32_t numerator, int32_t denominator);
  21. +
  22. + /**
  23. + * Divide two integers, returning the floor of the quotient.
  24. + * Unlike the built-in division, this is mathematically
  25. + * well-behaved. E.g., <code>-1/4</code> => 0 but
  26. + * <code>floorDivide(-1,4)</code> => -1.
  27. + * @param numerator the numerator
  28. + * @param denominator a divisor which must be != 0
  29. + * @return the floor of the quotient
  30. + */
  31. + static int64_t floorDivide(int64_t numerator, int64_t denominator);
  32. /**
  33. Index: source/i18n/persncal.cpp
  34. ===================================================================
  35. --- source/i18n/persncal.cpp (revision 40653)
  36. +++ source/i18n/persncal.cpp (revision 40654)
  37. @@ -214,5 +214,5 @@
  38. int32_t daysSinceEpoch = julianDay - PERSIAN_EPOCH;
  39. - year = 1 + ClockMath::floorDivide(33 * daysSinceEpoch + 3, 12053);
  40. + year = 1 + (int32_t)ClockMath::floorDivide(33 * (int64_t)daysSinceEpoch + 3, (int64_t)12053);
  41. int32_t farvardin1 = 365 * (year - 1) + ClockMath::floorDivide(8 * year + 21, 33);
  42. Index: source/test/intltest/calregts.cpp
  43. ===================================================================
  44. --- source/test/intltest/calregts.cpp (revision 40653)
  45. +++ source/test/intltest/calregts.cpp (revision 40654)
  46. @@ -13,4 +13,5 @@
  47. #include "calregts.h"
  48. +#include "unicode/calendar.h"
  49. #include "unicode/gregocal.h"
  50. #include "unicode/simpletz.h"
  51. @@ -91,4 +92,5 @@
  52. CASE(49,Test9019);
  53. CASE(50,TestT9452);
  54. + CASE(51,TestPersianCalOverflow);
  55. default: name = ""; break;
  56. }
  57. @@ -2946,4 +2948,34 @@
  58. }
  59. }
  60. +
  61. +/**
  62. + * @bug ticket 13454
  63. + */
  64. +void CalendarRegressionTest::TestPersianCalOverflow(void) {
  65. + const char* localeID = "bs_Cyrl@calendar=persian";
  66. + UErrorCode status = U_ZERO_ERROR;
  67. + Calendar* cal = Calendar::createInstance(Locale(localeID), status);
  68. + if(U_FAILURE(status)) {
  69. + dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID, u_errorName(status));
  70. + } else {
  71. + int32_t maxMonth = cal->getMaximum(UCAL_MONTH);
  72. + int32_t maxDayOfMonth = cal->getMaximum(UCAL_DATE);
  73. + int32_t jd, month, dayOfMonth;
  74. + for (jd = 67023580; jd <= 67023584; jd++) { // year 178171, int32_t overflow if jd >= 67023582
  75. + status = U_ZERO_ERROR;
  76. + cal->clear();
  77. + cal->set(UCAL_JULIAN_DAY, jd);
  78. + month = cal->get(UCAL_MONTH, status);
  79. + dayOfMonth = cal->get(UCAL_DATE, status);
  80. + if ( U_FAILURE(status) ) {
  81. + errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s\n", localeID, jd, u_errorName(status));
  82. + } else if (month > maxMonth || dayOfMonth > maxDayOfMonth) {
  83. + errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d\n",
  84. + localeID, jd, maxMonth, month, maxDayOfMonth, dayOfMonth);
  85. + }
  86. + }
  87. + delete cal;
  88. + }
  89. +}
  90. #endif /* #if !UCONFIG_NO_FORMATTING */
  91. Index: source/test/intltest/calregts.h
  92. ===================================================================
  93. --- source/test/intltest/calregts.h (revision 40653)
  94. +++ source/test/intltest/calregts.h (revision 40654)
  95. @@ -78,4 +78,5 @@
  96. void Test9019(void);
  97. void TestT9452(void);
  98. + void TestPersianCalOverflow(void);
  99. void printdate(GregorianCalendar *cal, const char *string);