summaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/icu/APKBUILD85
-rw-r--r--system/icu/CVE-2017-7867-7868.patch155
-rw-r--r--system/icu/icu-58.1-iterator-reset.patch124
-rw-r--r--system/icu/icu-60.2-always-use-utf8.patch11
4 files changed, 375 insertions, 0 deletions
diff --git a/system/icu/APKBUILD b/system/icu/APKBUILD
new file mode 100644
index 000000000..c1f3f1bf3
--- /dev/null
+++ b/system/icu/APKBUILD
@@ -0,0 +1,85 @@
+# Contributor: Sergey Lukin <sergej.lukin@gmail.com>
+# Maintainer: A. Wilcox <awilfox@adelielinux.org>
+pkgname=icu
+pkgver=62.1
+
+# convert x.y.z to x_y_z
+_ver=${pkgver//./_}
+
+pkgrel=2
+pkgdesc="International Components for Unicode library"
+url="http://www.icu-project.org/"
+arch="all"
+license="ICU"
+subpackages="$pkgname-dev $pkgname-doc $pkgname-libs"
+depends=
+checkdepends="diffutils"
+makedepends=
+source="http://download.icu-project.org/files/icu4c/${pkgver}/${pkgname}4c-$_ver-src.tgz
+ icu-60.2-always-use-utf8.patch
+ "
+
+# secfixes:
+# 57.1-r1:
+# - CVE-2016-6293
+# 58.1-r1:
+# - CVE-2016-7415
+# 58.2-r2:
+# - CVE-2017-7867
+# - CVE-2017-7868
+builddir="$srcdir"/icu/source
+
+prepare() {
+ cd "$builddir"
+ default_prepare
+ update_config_sub
+
+ # strtod_l() is not supported by musl; also xlocale.h is missing
+ # It is not possible to disable its use via configure switches or env vars
+ # so monkey patching is needed. Idea was stollen from openembedded
+ # https://github.com/openembedded/openembedded-core/blob/master/meta/recipes-support/icu/icu.inc#L30
+ sed -i -e 's,DU_HAVE_STRTOD_L=1,DU_HAVE_STRTOD_L=0,' configure.ac
+ sed -i -e 's,DU_HAVE_STRTOD_L=1,DU_HAVE_STRTOD_L=0,' configure
+
+ local x
+ # https://bugs.icu-project.org/trac/ticket/6102
+ for x in ARFLAGS CFLAGS CPPFLAGS CXXFLAGS FFLAGS LDFLAGS; do
+ sed -i -e "/^${x} =.*/s:@${x}@::" "config/Makefile.inc.in"
+ done
+}
+
+build() {
+ cd "$builddir"
+ ./configure \
+ --build=$CBUILD \
+ --host=$CHOST \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --with-data-packaging=library \
+ --disable-samples \
+ --mandir=/usr/share/man
+ make
+}
+
+check() {
+ # armhf tests fail with gensprep: Bus error
+ [ "$CARCH" != armhf ] || return 0
+ cd "$builddir"
+ make check
+}
+
+package() {
+ cd "$builddir"
+ make -j1 DESTDIR="$pkgdir" install
+ chmod +x "$pkgdir"/usr/bin/icu-config
+ install -Dm644 "$srcdir"/icu/license.html \
+ "$pkgdir"/usr/share/licenses/icu/license.html
+}
+
+libs() {
+ default_libs
+ replaces="icu"
+}
+
+sha512sums="8295f2754fb6907e2cc8f515dccca05530963b544e89a2b8e323cd0ddfdbbe0c9eba8b367c1dbc04d7bb906b66b1003fd545ca05298939747c832c9d4431cf2a icu4c-62_1-src.tgz
+f86c62422f38f6485c58d4766e629bab69e4b0e00fa910854e40e7db1ace299152eaefa99ae2fbab7465e65d3156cbea7124612defa60680db58ab5c34d6262f icu-60.2-always-use-utf8.patch"
diff --git a/system/icu/CVE-2017-7867-7868.patch b/system/icu/CVE-2017-7867-7868.patch
new file mode 100644
index 000000000..df18283c2
--- /dev/null
+++ b/system/icu/CVE-2017-7867-7868.patch
@@ -0,0 +1,155 @@
+Index: source/common/utext.cpp
+===================================================================
+--- source/common/utext.cpp (revision 39670)
++++ source/common/utext.cpp (revision 39671)
+@@ -848,7 +848,13 @@
+
+ // Chunk size.
+-// Must be less than 85, because of byte mapping from UChar indexes to native indexes.
+-// Worst case is three native bytes to one UChar. (Supplemenaries are 4 native bytes
+-// to two UChars.)
++// Must be less than 42 (256/6), because of byte mapping from UChar indexes to native indexes.
++// Worst case there are six UTF-8 bytes per UChar.
++// obsolete 6 byte form fd + 5 trails maps to fffd
++// obsolete 5 byte form fc + 4 trails maps to fffd
++// non-shortest 4 byte forms maps to fffd
++// normal supplementaries map to a pair of utf-16, two utf8 bytes per utf-16 unit
++// mapToUChars array size must allow for the worst case, 6.
++// This could be brought down to 4, by treating fd and fc as pure illegal,
++// rather than obsolete lead bytes. But that is not compatible with the utf-8 access macros.
+ //
+ enum { UTF8_TEXT_CHUNK_SIZE=32 };
+@@ -890,5 +896,5 @@
+ // one for a supplementary starting in the last normal position,
+ // and one for an entry for the buffer limit position.
+- uint8_t mapToUChars[UTF8_TEXT_CHUNK_SIZE*3+6]; // Map native offset from bufNativeStart to
++ uint8_t mapToUChars[UTF8_TEXT_CHUNK_SIZE*6+6]; // Map native offset from bufNativeStart to
+ // correspoding offset in filled part of buf.
+ int32_t align;
+@@ -1033,4 +1039,5 @@
+ u8b = (UTF8Buf *)ut->p; // the current buffer
+ mapIndex = ix - u8b->toUCharsMapStart;
++ U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
+ ut->chunkOffset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
+ return TRUE;
+@@ -1299,4 +1306,8 @@
+ // If index is at the end, there is no character there to look at.
+ if (ix != ut->b) {
++ // Note: this function will only move the index back if it is on a trail byte
++ // and there is a preceding lead byte and the sequence from the lead
++ // through this trail could be part of a valid UTF-8 sequence
++ // Otherwise the index remains unchanged.
+ U8_SET_CP_START(s8, 0, ix);
+ }
+@@ -1312,5 +1323,8 @@
+ uint8_t *mapToNative = u8b->mapToNative;
+ uint8_t *mapToUChars = u8b->mapToUChars;
+- int32_t toUCharsMapStart = ix - (UTF8_TEXT_CHUNK_SIZE*3 + 1);
++ int32_t toUCharsMapStart = ix - sizeof(UTF8Buf::mapToUChars) + 1;
++ // Note that toUCharsMapStart can be negative. Happens when the remaining
++ // text from current position to the beginning is less than the buffer size.
++ // + 1 because mapToUChars must have a slot at the end for the bufNativeLimit entry.
+ int32_t destIx = UTF8_TEXT_CHUNK_SIZE+2; // Start in the overflow region
+ // at end of buffer to leave room
+@@ -1339,4 +1353,5 @@
+ // Special case ASCII range for speed.
+ buf[destIx] = (UChar)c;
++ U_ASSERT(toUCharsMapStart <= srcIx);
+ mapToUChars[srcIx - toUCharsMapStart] = (uint8_t)destIx;
+ mapToNative[destIx] = (uint8_t)(srcIx - toUCharsMapStart);
+@@ -1368,4 +1383,5 @@
+ mapToUChars[sIx-- - toUCharsMapStart] = (uint8_t)destIx;
+ } while (sIx >= srcIx);
++ U_ASSERT(toUCharsMapStart <= (srcIx+1));
+
+ // Set native indexing limit to be the current position.
+@@ -1542,4 +1558,5 @@
+ U_ASSERT(index<=ut->chunkNativeLimit);
+ int32_t mapIndex = index - u8b->toUCharsMapStart;
++ U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
+ int32_t offset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
+ U_ASSERT(offset>=0 && offset<=ut->chunkLength);
+Index: source/test/intltest/utxttest.cpp
+===================================================================
+--- source/test/intltest/utxttest.cpp (revision 39670)
++++ source/test/intltest/utxttest.cpp (revision 39671)
+@@ -68,4 +68,6 @@
+ case 7: name = "Ticket12130";
+ if (exec) Ticket12130(); break;
++ case 8: name = "Ticket12888";
++ if (exec) Ticket12888(); break;
+ default: name = ""; break;
+ }
+@@ -1584,2 +1586,62 @@
+ utext_close(&ut);
+ }
++
++// Ticket 12888: bad handling of illegal utf-8 containing many instances of the archaic, now illegal,
++// six byte utf-8 forms. Original implementation had an assumption that
++// there would be at most three utf-8 bytes per UTF-16 code unit.
++// The five and six byte sequences map to a single replacement character.
++
++void UTextTest::Ticket12888() {
++ const char *badString =
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++ "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80";
++
++ UErrorCode status = U_ZERO_ERROR;
++ LocalUTextPointer ut(utext_openUTF8(NULL, badString, -1, &status));
++ TEST_SUCCESS(status);
++ for (;;) {
++ UChar32 c = utext_next32(ut.getAlias());
++ if (c == U_SENTINEL) {
++ break;
++ }
++ }
++ int32_t endIdx = utext_getNativeIndex(ut.getAlias());
++ if (endIdx != (int32_t)strlen(badString)) {
++ errln("%s:%d expected=%d, actual=%d", __FILE__, __LINE__, strlen(badString), endIdx);
++ return;
++ }
++
++ for (int32_t prevIndex = endIdx; prevIndex>0;) {
++ UChar32 c = utext_previous32(ut.getAlias());
++ int32_t currentIndex = utext_getNativeIndex(ut.getAlias());
++ if (c != 0xfffd) {
++ errln("%s:%d (expected, actual, index) = (%d, %d, %d)\n",
++ __FILE__, __LINE__, 0xfffd, c, currentIndex);
++ break;
++ }
++ if (currentIndex != prevIndex - 6) {
++ errln("%s:%d: wrong index. Expected, actual = %d, %d",
++ __FILE__, __LINE__, prevIndex - 6, currentIndex);
++ break;
++ }
++ prevIndex = currentIndex;
++ }
++}
+Index: source/test/intltest/utxttest.h
+===================================================================
+--- source/test/intltest/utxttest.h (revision 39670)
++++ source/test/intltest/utxttest.h (revision 39671)
+@@ -39,4 +39,5 @@
+ void Ticket10983();
+ void Ticket12130();
++ void Ticket12888();
+
+ private:
diff --git a/system/icu/icu-58.1-iterator-reset.patch b/system/icu/icu-58.1-iterator-reset.patch
new file mode 100644
index 000000000..24c7fa96d
--- /dev/null
+++ b/system/icu/icu-58.1-iterator-reset.patch
@@ -0,0 +1,124 @@
+Index: /icu/trunk/source/common/ulist.c
+===================================================================
+--- source/common/ulist.c (revision 39483)
++++ source/common/ulist.c (revision 39484)
+@@ -30,5 +30,4 @@
+
+ int32_t size;
+- int32_t currentIndex;
+ };
+
+@@ -52,5 +51,4 @@
+ newList->tail = NULL;
+ newList->size = 0;
+- newList->currentIndex = -1;
+
+ return newList;
+@@ -81,6 +79,7 @@
+ p->next->previous = p->previous;
+ }
+- list->curr = NULL;
+- list->currentIndex = 0;
++ if (p == list->curr) {
++ list->curr = p->next;
++ }
+ --list->size;
+ if (p->forceDelete) {
+@@ -151,5 +150,4 @@
+ list->head->previous = newItem;
+ list->head = newItem;
+- list->currentIndex++;
+ }
+
+@@ -194,5 +192,4 @@
+ curr = list->curr;
+ list->curr = curr->next;
+- list->currentIndex++;
+
+ return curr->data;
+@@ -210,5 +207,4 @@
+ if (list != NULL) {
+ list->curr = list->head;
+- list->currentIndex = 0;
+ }
+ }
+@@ -273,3 +269,2 @@
+ return (UList *)(en->context);
+ }
+-
+Index: /icu/trunk/source/i18n/ucol_res.cpp
+===================================================================
+--- source/i18n/ucol_res.cpp (revision 39483)
++++ source/i18n/ucol_res.cpp (revision 39484)
+@@ -681,4 +681,5 @@
+ }
+ memcpy(en, &defaultKeywordValues, sizeof(UEnumeration));
++ ulist_resetList(sink.values); // Initialize the iterator.
+ en->context = sink.values;
+ sink.values = NULL; // Avoid deletion in the sink destructor.
+Index: /icu/trunk/source/test/intltest/apicoll.cpp
+===================================================================
+--- source/test/intltest/apicoll.cpp (revision 39483)
++++ source/test/intltest/apicoll.cpp (revision 39484)
+@@ -82,14 +82,7 @@
+ col = Collator::createInstance(Locale::getEnglish(), success);
+ if (U_FAILURE(success)){
+- errcheckln(success, "Default Collator creation failed. - %s", u_errorName(success));
+- return;
+- }
+-
+- StringEnumeration* kwEnum = col->getKeywordValuesForLocale("", Locale::getEnglish(),true,success);
+- if (U_FAILURE(success)){
+- errcheckln(success, "Get Keyword Values for Locale failed. - %s", u_errorName(success));
+- return;
+- }
+- delete kwEnum;
++ errcheckln(success, "English Collator creation failed. - %s", u_errorName(success));
++ return;
++ }
+
+ col->getVersion(versionArray);
+@@ -230,4 +223,27 @@
+ delete aFrCol;
+ delete junk;
++}
++
++void CollationAPITest::TestKeywordValues() {
++ IcuTestErrorCode errorCode(*this, "TestKeywordValues");
++ LocalPointer<Collator> col(Collator::createInstance(Locale::getEnglish(), errorCode));
++ if (errorCode.logIfFailureAndReset("English Collator creation failed")) {
++ return;
++ }
++
++ LocalPointer<StringEnumeration> kwEnum(
++ col->getKeywordValuesForLocale("collation", Locale::getEnglish(), TRUE, errorCode));
++ if (errorCode.logIfFailureAndReset("Get Keyword Values for English Collator failed")) {
++ return;
++ }
++ assertTrue("expect at least one collation tailoring for English", kwEnum->count(errorCode) > 0);
++ const char *kw;
++ UBool hasStandard = FALSE;
++ while ((kw = kwEnum->next(NULL, errorCode)) != NULL) {
++ if (strcmp(kw, "standard") == 0) {
++ hasStandard = TRUE;
++ }
++ }
++ assertTrue("expect at least the 'standard' collation tailoring for English", hasStandard);
+ }
+
+@@ -2467,4 +2483,5 @@
+ TESTCASE_AUTO_BEGIN;
+ TESTCASE_AUTO(TestProperty);
++ TESTCASE_AUTO(TestKeywordValues);
+ TESTCASE_AUTO(TestOperators);
+ TESTCASE_AUTO(TestDuplicate);
+Index: /icu/trunk/source/test/intltest/apicoll.h
+===================================================================
+--- source/test/intltest/apicoll.h (revision 39483)
++++ source/test/intltest/apicoll.h (revision 39484)
+@@ -36,4 +36,5 @@
+ */
+ void TestProperty(/* char* par */);
++ void TestKeywordValues();
+
+ /**
diff --git a/system/icu/icu-60.2-always-use-utf8.patch b/system/icu/icu-60.2-always-use-utf8.patch
new file mode 100644
index 000000000..773687174
--- /dev/null
+++ b/system/icu/icu-60.2-always-use-utf8.patch
@@ -0,0 +1,11 @@
+--- source/common/unicode/platform.h 2017-10-25 13:41:15.000000000 -0500
++++ source/common/unicode/platform.h 2018-04-04 02:07:28.851222016 -0500
+@@ -634,7 +634,7 @@
+ #elif U_PLATFORM == U_PF_ANDROID || U_PLATFORM_IS_DARWIN_BASED
+ # define U_CHARSET_IS_UTF8 1
+ #else
+-# define U_CHARSET_IS_UTF8 0
++# define U_CHARSET_IS_UTF8 1
+ #endif
+
+ /** @} */