5a25b0a
From f247f08e370626bbb427acd8f4a400fd875350a3 Mon Sep 17 00:00:00 2001
5a25b0a
Message-Id: <f247f08e370626bbb427acd8f4a400fd875350a3.1531842113.git.erack@redhat.com>
5a25b0a
From: Eike Rathke <erack@redhat.com>
5a25b0a
Date: Tue, 17 Apr 2018 20:13:52 +0200
5a25b0a
Subject: [PATCH] Upgrade to ICU 61.1
5a25b0a
MIME-Version: 1.0
5a25b0a
Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
5a25b0a
5a25b0a
This is a multi-part message in MIME format.
5a25b0a
--------------erAck-patch-parts
5a25b0a
Content-Type: text/plain; charset=UTF-8; format=fixed
5a25b0a
Content-Transfer-Encoding: 8bit
5a25b0a
5a25b0a
5a25b0a
Change-Id: I89c1c3d13d85decc72576744de2a16d20471d29d
5a25b0a
Reviewed-on: https://gerrit.libreoffice.org/53064
5a25b0a
Tested-by: Jenkins <ci@libreoffice.org>
5a25b0a
Reviewed-by: Eike Rathke <erack@redhat.com>
5a25b0a
---
5a25b0a
 configure.ac                                  |   4 +-
5a25b0a
 download.lst                                  |   8 +-
5a25b0a
 external/icu/UnpackedTarball_icu.mk           |   3 +-
5a25b0a
 ...patch.1 => icu4c-61-werror-shadow.patch.1} |  30 ++-
5a25b0a
 external/icu/icu4c-khmerbreakengine.patch.1   | 246 +++++++++---------
5a25b0a
 external/icu/icu4c-ubsan.patch.1              |  91 -------
5a25b0a
 6 files changed, 147 insertions(+), 235 deletions(-)
5a25b0a
 rename external/icu/{icu4c-59-werror-shadow.patch.1 => icu4c-61-werror-shadow.patch.1} (50%)
5a25b0a
 delete mode 100644 external/icu/icu4c-ubsan.patch.1
5a25b0a
5a25b0a
5a25b0a
--------------erAck-patch-parts
5a25b0a
Content-Type: text/x-patch; name="0001-Upgrade-to-ICU-61.1.patch"
5a25b0a
Content-Transfer-Encoding: 8bit
5a25b0a
Content-Disposition: attachment; filename="0001-Upgrade-to-ICU-61.1.patch"
5a25b0a
5a25b0a
diff --git a/configure.ac b/configure.ac
5a25b0a
index bdc374699cb9..458f9f3c2735 100644
5a25b0a
--- a/configure.ac
5a25b0a
+++ b/configure.ac
5a25b0a
@@ -9001,8 +9001,8 @@ SYSTEM_GENBRK=
5a25b0a
 SYSTEM_GENCCODE=
5a25b0a
 SYSTEM_GENCMN=
5a25b0a
 
5a25b0a
-ICU_MAJOR=60
5a25b0a
-ICU_MINOR=2
5a25b0a
+ICU_MAJOR=61
5a25b0a
+ICU_MINOR=1
5a25b0a
 ICU_RECLASSIFIED_PREPEND_SET_EMPTY="TRUE"
5a25b0a
 ICU_RECLASSIFIED_CONDITIONAL_JAPANESE_STARTER="TRUE"
5a25b0a
 ICU_RECLASSIFIED_HEBREW_LETTER="TRUE"
5a25b0a
diff --git a/download.lst b/download.lst
5a25b0a
index 0a1fa65396d1..76f067bff4d7 100644
5a25b0a
--- a/download.lst
5a25b0a
+++ b/download.lst
5a25b0a
@@ -102,10 +102,10 @@ export HUNSPELL_SHA256SUM := 3cd9ceb062fe5814f668e4f22b2fa6e3ba0b339b921739541ce
5a25b0a
 export HUNSPELL_TARBALL := hunspell-1.6.2.tar.gz
5a25b0a
 export HYPHEN_SHA256SUM := 304636d4eccd81a14b6914d07b84c79ebb815288c76fe027b9ebff6ff24d5705
5a25b0a
 export HYPHEN_TARBALL := 5ade6ae2a99bc1e9e57031ca88d36dad-hyphen-2.8.8.tar.gz
5a25b0a
-export ICU_SHA256SUM := f073ea8f35b926d70bb33e6577508aa642a8b316a803f11be20af384811db418
5a25b0a
-export ICU_TARBALL := icu4c-60_2-src.tgz
5a25b0a
-export ICU_DATA_SHA256SUM := 68f42ad0c9e0a5a5af8eba0577ba100833912288bad6e4d1f42ff480bbcfd4a9
5a25b0a
-export ICU_DATA_TARBALL := icu4c-60_2-data.zip
5a25b0a
+export ICU_SHA256SUM := d007f89ae8a2543a53525c74359b65b36412fa84b3349f1400be6dcf409fafef
5a25b0a
+export ICU_TARBALL := icu4c-61_1-src.tgz
5a25b0a
+export ICU_DATA_SHA256SUM := d149ed0985b5a6e16a9d8ed66f105dd58fd334c276779f74241cfa656ed2830a
5a25b0a
+export ICU_DATA_TARBALL := icu4c-61_1-data.zip
5a25b0a
 export JFREEREPORT_FLOW_ENGINE_SHA256SUM := 233f66e8d25c5dd971716d4200203a612a407649686ef3b52075d04b4c9df0dd
5a25b0a
 export JFREEREPORT_FLOW_ENGINE_TARBALL := ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip
5a25b0a
 export JFREEREPORT_FLUTE_SHA256SUM := 1b5b24f7bc543c0362b667692f78db8bab4ed6dafc6172f104d0bd3757d8a133
5a25b0a
diff --git a/external/icu/UnpackedTarball_icu.mk b/external/icu/UnpackedTarball_icu.mk
5a25b0a
index a4d0b16ecb36..b81cdaab6242 100644
5a25b0a
--- a/external/icu/UnpackedTarball_icu.mk
5a25b0a
+++ b/external/icu/UnpackedTarball_icu.mk
5a25b0a
@@ -27,15 +27,14 @@ $(eval $(call gb_UnpackedTarball_add_patches,icu,\
5a25b0a
 	external/icu/icu4c-solarisgcc.patch.1 \
5a25b0a
 	external/icu/icu4c-mkdir.patch.1 \
5a25b0a
 	external/icu/icu4c-$(if $(filter ANDROID,$(OS)),android,rpath).patch.1 \
5a25b0a
-	external/icu/icu4c-ubsan.patch.1 \
5a25b0a
 	external/icu/icu4c-icu11100.patch.1 \
5a25b0a
 	external/icu/icu4c-scriptrun.patch.1 \
5a25b0a
 	external/icu/icu4c-rtti.patch.1 \
5a25b0a
 	external/icu/icu4c-clang-cl.patch.1 \
5a25b0a
 	$(if $(filter-out ANDROID,$(OS)),external/icu/icu4c-icudata-stdlibs.patch.1) \
5a25b0a
 	external/icu/icu4c-khmerbreakengine.patch.1 \
5a25b0a
-	external/icu/icu4c-59-werror-shadow.patch.1 \
5a25b0a
 	external/icu/ofz4860.patch.2 \
5a25b0a
+	external/icu/icu4c-61-werror-shadow.patch.1 \
5a25b0a
 ))
5a25b0a
 
5a25b0a
 $(eval $(call gb_UnpackedTarball_add_file,icu,source/data/brkitr/khmerdict.dict,external/icu/khmerdict.dict))
5a25b0a
diff --git a/external/icu/icu4c-59-werror-shadow.patch.1 b/external/icu/icu4c-61-werror-shadow.patch.1
5a25b0a
similarity index 50%
5a25b0a
rename from external/icu/icu4c-59-werror-shadow.patch.1
5a25b0a
rename to external/icu/icu4c-61-werror-shadow.patch.1
5a25b0a
index fb88244aff13..b00f76317eff 100644
5a25b0a
--- a/external/icu/icu4c-59-werror-shadow.patch.1
5a25b0a
+++ b/external/icu/icu4c-61-werror-shadow.patch.1
5a25b0a
@@ -1,33 +1,35 @@
5a25b0a
+# https://ssl.icu-project.org/trac/ticket/13709
5a25b0a
+# Werror=shadow fails for unistr.h
5a25b0a
 diff -ur icu.org/source/common/unicode/unistr.h icu/source/common/unicode/unistr.h
5a25b0a
---- icu.org/source/common/unicode/unistr.h	2017-03-29 06:44:37.000000000 +0200
5a25b0a
-+++ icu/source/common/unicode/unistr.h	2017-04-24 11:59:51.782076511 +0200
5a25b0a
-@@ -3080,11 +3080,11 @@
5a25b0a
+--- icu.org/source/common/unicode/unistr.h	2018-03-26 15:38:29.000000000 +0200
5a25b0a
++++ icu/source/common/unicode/unistr.h	2018-04-18 10:44:16.321188314 +0200
5a25b0a
+@@ -3053,11 +3053,11 @@
5a25b0a
     * uint16_t * constructor.
5a25b0a
     * Delegates to UnicodeString(const char16_t *, int32_t).
5a25b0a
     * @param text UTF-16 string
5a25b0a
 -   * @param length string length
5a25b0a
-+   * @param length_ string length
5a25b0a
-    * @draft ICU 59
5a25b0a
++   * @param textLength string length
5a25b0a
+    * @stable ICU 59
5a25b0a
     */
5a25b0a
 -  UnicodeString(const uint16_t *text, int32_t length) :
5a25b0a
 -      UnicodeString(ConstChar16Ptr(text), length) {}
5a25b0a
-+  UnicodeString(const uint16_t *text, int32_t length_) :
5a25b0a
-+      UnicodeString(ConstChar16Ptr(text), length_) {}
5a25b0a
++  UnicodeString(const uint16_t *text, int32_t textLength) :
5a25b0a
++      UnicodeString(ConstChar16Ptr(text), textLength) {}
5a25b0a
  #endif
5a25b0a
  
5a25b0a
-   /*
5a25b0a
-@@ -3097,11 +3097,11 @@
5a25b0a
+ #if U_SIZEOF_WCHAR_T==2 || defined(U_IN_DOXYGEN)
5a25b0a
+@@ -3066,11 +3066,11 @@
5a25b0a
     * (Only defined if U_SIZEOF_WCHAR_T==2.)
5a25b0a
     * Delegates to UnicodeString(const char16_t *, int32_t).
5a25b0a
     * @param text NUL-terminated UTF-16 string
5a25b0a
 -   * @param length string length
5a25b0a
-+   * @param length_ string length
5a25b0a
-    * @draft ICU 59
5a25b0a
++   * @param textLength string length
5a25b0a
+    * @stable ICU 59
5a25b0a
     */
5a25b0a
 -  UnicodeString(const wchar_t *text, int32_t length) :
5a25b0a
 -      UnicodeString(ConstChar16Ptr(text), length) {}
5a25b0a
-+  UnicodeString(const wchar_t *text, int32_t length_) :
5a25b0a
-+      UnicodeString(ConstChar16Ptr(text), length_) {}
5a25b0a
++  UnicodeString(const wchar_t *text, int32_t textLength) :
5a25b0a
++      UnicodeString(ConstChar16Ptr(text), textLength) {}
5a25b0a
  #endif
5a25b0a
  
5a25b0a
-   /*
5a25b0a
+   /**
5a25b0a
diff --git a/external/icu/icu4c-khmerbreakengine.patch.1 b/external/icu/icu4c-khmerbreakengine.patch.1
5a25b0a
index 6b45b3743611..9f134dd961b1 100644
5a25b0a
--- a/external/icu/icu4c-khmerbreakengine.patch.1
5a25b0a
+++ b/external/icu/icu4c-khmerbreakengine.patch.1
5a25b0a
@@ -1,16 +1,18 @@
5a25b0a
 diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
---- icu.org/source/common/dictbe.cpp	2017-01-20 01:20:31.000000000 +0100
5a25b0a
-+++ icu/source/common/dictbe.cpp	2017-04-21 23:14:23.845894374 +0200
5a25b0a
-@@ -29,8 +29,17 @@
5a25b0a
+--- icu.org/source/common/dictbe.cpp	2018-03-26 15:38:30.000000000 +0200
5a25b0a
++++ icu/source/common/dictbe.cpp	2018-04-17 17:55:38.620944919 +0200
5a25b0a
+@@ -29,7 +29,19 @@
5a25b0a
   ******************************************************************
5a25b0a
   */
5a25b0a
  
5a25b0a
--DictionaryBreakEngine::DictionaryBreakEngine(uint32_t breakTypes) {
5a25b0a
-+DictionaryBreakEngine::DictionaryBreakEngine(uint32_t breakTypes) :
5a25b0a
-+    clusterLimit(3)
5a25b0a
-+{
5a25b0a
+-DictionaryBreakEngine::DictionaryBreakEngine() {
5a25b0a
++DictionaryBreakEngine::DictionaryBreakEngine()
5a25b0a
++    : fTypes(0), clusterLimit(0) {
5a25b0a
++}
5a25b0a
++
5a25b0a
++DictionaryBreakEngine::DictionaryBreakEngine(uint32_t breakTypes)
5a25b0a
++    : fTypes(breakTypes), clusterLimit(3) {
5a25b0a
 +    UErrorCode status = U_ZERO_ERROR;
5a25b0a
-     fTypes = breakTypes;
5a25b0a
 +    fViramaSet.applyPattern(UNICODE_STRING_SIMPLE("[[:ccc=VR:]]"), status);
5a25b0a
 +
5a25b0a
 +    // note Skip Sets contain fIgnoreSet characters too.
5a25b0a
@@ -20,16 +22,7 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
  }
5a25b0a
  
5a25b0a
  DictionaryBreakEngine::~DictionaryBreakEngine() {
5a25b0a
-@@ -92,7 +101,7 @@
5a25b0a
-         result = divideUpDictionaryRange(text, rangeStart, rangeEnd, foundBreaks);
5a25b0a
-         utext_setNativeIndex(text, current);
5a25b0a
-     }
5a25b0a
--    
5a25b0a
-+
5a25b0a
-     return result;
5a25b0a
- }
5a25b0a
- 
5a25b0a
-@@ -103,6 +112,169 @@
5a25b0a
+@@ -76,6 +88,169 @@
5a25b0a
      fSet.compact();
5a25b0a
  }
5a25b0a
  
5a25b0a
@@ -199,7 +192,7 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
  /*
5a25b0a
   ******************************************************************
5a25b0a
   * PossibleWord
5a25b0a
-@@ -130,35 +302,35 @@
5a25b0a
+@@ -103,35 +278,35 @@
5a25b0a
  public:
5a25b0a
      PossibleWord() : count(0), prefix(0), offset(-1), mark(0), current(0) {};
5a25b0a
      ~PossibleWord() {};
5a25b0a
@@ -244,7 +237,7 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
          // Dictionary leaves text after longest prefix, not longest word. Back up.
5a25b0a
          if (count <= 0) {
5a25b0a
              utext_setNativeIndex(text, start);
5a25b0a
-@@ -830,51 +1002,28 @@
5a25b0a
+@@ -803,51 +978,28 @@
5a25b0a
   * KhmerBreakEngine
5a25b0a
   */
5a25b0a
  
5a25b0a
@@ -265,7 +258,8 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 -static const int32_t KHMER_MIN_WORD_SPAN = KHMER_MIN_WORD * 2;
5a25b0a
 -
5a25b0a
  KhmerBreakEngine::KhmerBreakEngine(DictionaryMatcher *adoptDictionary, UErrorCode &status)
5a25b0a
-     : DictionaryBreakEngine((1 << UBRK_WORD) | (1 << UBRK_LINE)),
5a25b0a
+-    : DictionaryBreakEngine(),
5a25b0a
++    : DictionaryBreakEngine((1 << UBRK_WORD) | (1 << UBRK_LINE)),
5a25b0a
        fDictionary(adoptDictionary)
5a25b0a
  {
5a25b0a
 -    fKhmerWordSet.applyPattern(UNICODE_STRING_SIMPLE("[[:Khmr:]&[:LineBreak=SA:]]"), status);
5a25b0a
@@ -301,13 +295,13 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 -    fEndWordSet.compact();
5a25b0a
 -    fBeginWordSet.compact();
5a25b0a
 -//    fSuffixSet.compact();
5a25b0a
-+	fIgnoreSet.compact();
5a25b0a
-+	fBaseSet.compact();
5a25b0a
-+	fPuncSet.compact();
5a25b0a
++    fIgnoreSet.compact();
5a25b0a
++    fBaseSet.compact();
5a25b0a
++    fPuncSet.compact();
5a25b0a
  }
5a25b0a
  
5a25b0a
  KhmerBreakEngine::~KhmerBreakEngine() {
5a25b0a
-@@ -886,180 +1035,204 @@
5a25b0a
+@@ -859,180 +1011,204 @@
5a25b0a
                                                  int32_t rangeStart,
5a25b0a
                                                  int32_t rangeEnd,
5a25b0a
                                                  UVector32 &foundBreaks ) const {
5a25b0a
@@ -350,17 +344,6 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 +            foundBreaks.push(rangeEnd, status);
5a25b0a
 +        return foundBreaks.size() - wordsFound;
5a25b0a
 +    }
5a25b0a
-+
5a25b0a
-+    scanStart = rangeStart;
5a25b0a
-+    scanWJ(text, scanStart, rangeEnd, before, after);
5a25b0a
-+    if (startZwsp || initAfter >= before) {
5a25b0a
-+        after = initAfter;
5a25b0a
-+        before = 0;
5a25b0a
-+    }
5a25b0a
-+    if (!endZwsp && after > finalBefore && after < rangeEnd)
5a25b0a
-+        endZwsp = true;
5a25b0a
-+    if (endZwsp && before > finalBefore)
5a25b0a
-+        before = finalBefore;
5a25b0a
  
5a25b0a
 -    while (U_SUCCESS(status) && (current = (int32_t)utext_getNativeIndex(text)) < rangeEnd) {
5a25b0a
 -        cuWordLength = 0;
5a25b0a
@@ -375,7 +358,17 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 -            cpWordLength = words[wordsFound % KHMER_LOOKAHEAD].markedCPLength();
5a25b0a
 -            wordsFound += 1;
5a25b0a
 -        }
5a25b0a
--
5a25b0a
++    scanStart = rangeStart;
5a25b0a
++    scanWJ(text, scanStart, rangeEnd, before, after);
5a25b0a
++    if (startZwsp || initAfter >= before) {
5a25b0a
++        after = initAfter;
5a25b0a
++        before = 0;
5a25b0a
++    }
5a25b0a
++    if (!endZwsp && after > finalBefore && after < rangeEnd)
5a25b0a
++        endZwsp = true;
5a25b0a
++    if (endZwsp && before > finalBefore)
5a25b0a
++        before = finalBefore;
5a25b0a
+ 
5a25b0a
 -        // If there was more than one, see which one can take us forward the most words
5a25b0a
 -        else if (candidates > 1) {
5a25b0a
 -            // If we're already at the end of the range, we're done
5a25b0a
@@ -390,22 +383,6 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 -                        words[wordsFound % KHMER_LOOKAHEAD].markCurrent();
5a25b0a
 -                        wordsMatched = 2;
5a25b0a
 -                    }
5a25b0a
--
5a25b0a
--                    // If we're already at the end of the range, we're done
5a25b0a
--                    if ((int32_t)utext_getNativeIndex(text) >= rangeEnd) {
5a25b0a
--                        goto foundBest;
5a25b0a
--                    }
5a25b0a
--
5a25b0a
--                    // See if any of the possible second words is followed by a third word
5a25b0a
--                    do {
5a25b0a
--                        // If we find a third word, stop right away
5a25b0a
--                        if (words[(wordsFound + 2) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd)) {
5a25b0a
--                            words[wordsFound % KHMER_LOOKAHEAD].markCurrent();
5a25b0a
--                            goto foundBest;
5a25b0a
--                        }
5a25b0a
--                    }
5a25b0a
--                    while (words[(wordsFound + 1) % KHMER_LOOKAHEAD].backUp(text));
5a25b0a
--                }
5a25b0a
 +    utext_setNativeIndex(text, rangeStart);
5a25b0a
 +    int32_t numCodePts = rangeEnd - rangeStart;
5a25b0a
 +    // bestSnlp[i] is the snlp of the best segmentation of the first i
5a25b0a
@@ -415,7 +392,11 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 +    for(int32_t i = 1; i <= numCodePts; i++) {
5a25b0a
 +        bestSnlp.addElement(kuint32max, status);
5a25b0a
 +    }
5a25b0a
-+
5a25b0a
+ 
5a25b0a
+-                    // If we're already at the end of the range, we're done
5a25b0a
+-                    if ((int32_t)utext_getNativeIndex(text) >= rangeEnd) {
5a25b0a
+-                        goto foundBest;
5a25b0a
+-                    }
5a25b0a
 +    // prev[i] is the index of the last code point in the previous word in
5a25b0a
 +    // the best segmentation of the first i characters. Note negative implies
5a25b0a
 +	// that the code point is part of an unknown word.
5a25b0a
@@ -423,7 +404,17 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 +    for(int32_t i = 0; i <= numCodePts; i++) {
5a25b0a
 +        prev.addElement(kuint32max, status);
5a25b0a
 +    }
5a25b0a
-+
5a25b0a
+ 
5a25b0a
+-                    // See if any of the possible second words is followed by a third word
5a25b0a
+-                    do {
5a25b0a
+-                        // If we find a third word, stop right away
5a25b0a
+-                        if (words[(wordsFound + 2) % KHMER_LOOKAHEAD].candidates(text, fDictionary, rangeEnd)) {
5a25b0a
+-                            words[wordsFound % KHMER_LOOKAHEAD].markCurrent();
5a25b0a
+-                            goto foundBest;
5a25b0a
+-                        }
5a25b0a
+-                    }
5a25b0a
+-                    while (words[(wordsFound + 1) % KHMER_LOOKAHEAD].backUp(text));
5a25b0a
+-                }
5a25b0a
 +    const int32_t maxWordSize = 20;
5a25b0a
 +    UVector32 values(maxWordSize, status);
5a25b0a
 +    values.setSize(maxWordSize);
5a25b0a
@@ -528,27 +519,17 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 -                if (cuWordLength <= 0) {
5a25b0a
 -                    wordsFound += 1;
5a25b0a
 -                }
5a25b0a
--
5a25b0a
--                // Update the length with the passed-over characters
5a25b0a
--                cuWordLength += chars;
5a25b0a
--            }
5a25b0a
--            else {
5a25b0a
--                // Back up to where we were for next iteration
5a25b0a
--                utext_setNativeIndex(text, current+cuWordLength);
5a25b0a
 +                } while (fMarkSet.contains(c) || fIgnoreSet.contains(c));
5a25b0a
 +                values.setElementAt(BADSNLP, count);
5a25b0a
 +                lengths.setElementAt(utext_getNativeIndex(text) - currix, count++);
5a25b0a
 +            } else {
5a25b0a
 +                values.setElementAt(BADSNLP, count);
5a25b0a
 +                lengths.setElementAt(1, count++);
5a25b0a
-             }
5a25b0a
-         }
5a25b0a
++            }
5a25b0a
++        }
5a25b0a
  
5a25b0a
--        // Never stop before a combining mark.
5a25b0a
--        int32_t currPos;
5a25b0a
--        while ((currPos = (int32_t)utext_getNativeIndex(text)) < rangeEnd && fMarkSet.contains(utext_current32(text))) {
5a25b0a
--            utext_next32(text);
5a25b0a
--            cuWordLength += (int32_t)utext_getNativeIndex(text) - currPos;
5a25b0a
+-                // Update the length with the passed-over characters
5a25b0a
+-                cuWordLength += chars;
5a25b0a
 +        for (int32_t j = 0; j < count; j++) {
5a25b0a
 +            uint32_t v = values.elementAti(j);
5a25b0a
 +            int32_t newSnlp = bestSnlp.elementAti(i) + v;
5a25b0a
@@ -559,7 +540,10 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 +                ++ln;
5a25b0a
 +                utext_next32(text);
5a25b0a
 +                c = utext_current32(text);
5a25b0a
-+            }
5a25b0a
+             }
5a25b0a
+-            else {
5a25b0a
+-                // Back up to where we were for next iteration
5a25b0a
+-                utext_setNativeIndex(text, current+cuWordLength);
5a25b0a
 +            int32_t ln_j_i = ln + i;   // yes really i!
5a25b0a
 +            if (newSnlp < bestSnlp.elementAti(ln_j_i)) {
5a25b0a
 +                if (v == BADSNLP) {
5a25b0a
@@ -572,9 +556,38 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 +                else
5a25b0a
 +                    prev.setElementAt(i, ln_j_i);
5a25b0a
 +                bestSnlp.setElementAt(newSnlp, ln_j_i);
5a25b0a
-+            }
5a25b0a
+             }
5a25b0a
          }
5a25b0a
 -
5a25b0a
+-        // Never stop before a combining mark.
5a25b0a
+-        int32_t currPos;
5a25b0a
+-        while ((currPos = (int32_t)utext_getNativeIndex(text)) < rangeEnd && fMarkSet.contains(utext_current32(text))) {
5a25b0a
+-            utext_next32(text);
5a25b0a
+-            cuWordLength += (int32_t)utext_getNativeIndex(text) - currPos;
5a25b0a
++    }
5a25b0a
++    // Start pushing the optimal offset index into t_boundary (t for tentative).
5a25b0a
++    // prev[numCodePts] is guaranteed to be meaningful.
5a25b0a
++    // We'll first push in the reverse order, i.e.,
5a25b0a
++    // t_boundary[0] = numCodePts, and afterwards do a swap.
5a25b0a
++    UVector32 t_boundary(numCodePts+1, status);
5a25b0a
++
5a25b0a
++    int32_t numBreaks = 0;
5a25b0a
++    // No segmentation found, set boundary to end of range
5a25b0a
++    while (numCodePts >= 0 && (uint32_t)bestSnlp.elementAti(numCodePts) == kuint32max) {
5a25b0a
++        --numCodePts;
5a25b0a
++    }
5a25b0a
++    if (numCodePts < 0) {
5a25b0a
++        t_boundary.addElement(numCodePts, status);
5a25b0a
++        numBreaks++;
5a25b0a
++    } else {
5a25b0a
++        for (int32_t i = numCodePts; (uint32_t)i != kuint32max; i = prev.elementAti(i)) {
5a25b0a
++            if (i < 0) i = -i;
5a25b0a
++            t_boundary.addElement(i, status);
5a25b0a
++            numBreaks++;
5a25b0a
+         }
5a25b0a
++        U_ASSERT(prev.elementAti(t_boundary.elementAti(numBreaks - 1)) == 0);
5a25b0a
++    }
5a25b0a
+ 
5a25b0a
 -        // Look ahead for possible suffixes if a dictionary word does not follow.
5a25b0a
 -        // We do this in code rather than using a rule so that the heuristic
5a25b0a
 -        // resynch continues to function. For example, one of the suffix characters
5a25b0a
@@ -616,30 +629,6 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
 -        // Did we find a word on this iteration? If so, push it on the break stack
5a25b0a
 -        if (cuWordLength > 0) {
5a25b0a
 -            foundBreaks.push((current+cuWordLength), status);
5a25b0a
-+    }
5a25b0a
-+    // Start pushing the optimal offset index into t_boundary (t for tentative).
5a25b0a
-+    // prev[numCodePts] is guaranteed to be meaningful.
5a25b0a
-+    // We'll first push in the reverse order, i.e.,
5a25b0a
-+    // t_boundary[0] = numCodePts, and afterwards do a swap.
5a25b0a
-+    UVector32 t_boundary(numCodePts+1, status);
5a25b0a
-+
5a25b0a
-+    int32_t numBreaks = 0;
5a25b0a
-+    // No segmentation found, set boundary to end of range
5a25b0a
-+    while (numCodePts >= 0 && (uint32_t)bestSnlp.elementAti(numCodePts) == kuint32max) {
5a25b0a
-+        --numCodePts;
5a25b0a
-+    }
5a25b0a
-+    if (numCodePts < 0) {
5a25b0a
-+        t_boundary.addElement(numCodePts, status);
5a25b0a
-+        numBreaks++;
5a25b0a
-+    } else {
5a25b0a
-+        for (int32_t i = numCodePts; (uint32_t)i != kuint32max; i = prev.elementAti(i)) {
5a25b0a
-+            if (i < 0) i = -i;
5a25b0a
-+            t_boundary.addElement(i, status);
5a25b0a
-+            numBreaks++;
5a25b0a
-+        }
5a25b0a
-+        U_ASSERT(prev.elementAti(t_boundary.elementAti(numBreaks - 1)) == 0);
5a25b0a
-+    }
5a25b0a
-+
5a25b0a
 +    // Now that we're done, convert positions in t_boundary[] (indices in
5a25b0a
 +    // the normalized input string) back to indices in the original input UText
5a25b0a
 +    // while reversing t_boundary and pushing values to foundBreaks.
5a25b0a
@@ -669,38 +658,35 @@ diff -ur icu.org/source/common/dictbe.cpp icu/source/common/dictbe.cpp
5a25b0a
  
5a25b0a
  #if !UCONFIG_NO_NORMALIZATION
5a25b0a
 diff -ur icu.org/source/common/dictbe.h icu/source/common/dictbe.h
5a25b0a
---- icu.org/source/common/dictbe.h	2017-01-20 01:20:31.000000000 +0100
5a25b0a
-+++ icu/source/common/dictbe.h	2017-04-21 23:14:23.845894374 +0200
5a25b0a
-@@ -34,6 +34,15 @@
5a25b0a
+--- icu.org/source/common/dictbe.h	2018-03-26 15:38:30.000000000 +0200
5a25b0a
++++ icu/source/common/dictbe.h	2018-04-17 14:55:33.307639865 +0200
5a25b0a
+@@ -34,7 +34,8 @@
5a25b0a
+  * threads without synchronization.

5a25b0a
   */
5a25b0a
  class DictionaryBreakEngine : public LanguageBreakEngine {
5a25b0a
-  private:
5a25b0a
-+
5a25b0a
-+  /**
5a25b0a
-+   * 

Default constructor.

5a25b0a
-+   *
5a25b0a
-+   */
5a25b0a
-+  DictionaryBreakEngine();
5a25b0a
-+
5a25b0a
+- private:
5a25b0a
 + protected:
5a25b0a
 +
5a25b0a
      /**
5a25b0a
       * The set of characters handled by this engine
5a25b0a
       * @internal
5a25b0a
-@@ -48,11 +57,63 @@
5a25b0a
+@@ -42,14 +43,84 @@
5a25b0a
  
5a25b0a
-   uint32_t      fTypes;
5a25b0a
+   UnicodeSet    fSet;
5a25b0a
  
5a25b0a
 +  const int32_t WJ   = 0x2060;
5a25b0a
 +  const int32_t ZWSP = 0x200B;
5a25b0a
 +
5a25b0a
-   /**
5a25b0a
--   * 

Default constructor.

5a25b0a
--   *
5a25b0a
++  /**
5a25b0a
++   * The break types it was constructed with
5a25b0a
++   * @internal
5a25b0a
++   */
5a25b0a
++  uint32_t      fTypes;
5a25b0a
++
5a25b0a
++  /**
5a25b0a
 +   * A Unicode set of all viramas
5a25b0a
 +   * @internal
5a25b0a
-    */
5a25b0a
--  DictionaryBreakEngine();
5a25b0a
++   */
5a25b0a
 +  UnicodeSet    fViramaSet;
5a25b0a
 +
5a25b0a
 +  /**
5a25b0a
@@ -751,10 +737,26 @@ diff -ur icu.org/source/common/dictbe.h icu/source/common/dictbe.h
5a25b0a
 +  bool scanAfterEnd(UText *text, int32_t rangeEnd, int32_t& end, bool &doBreak) const;
5a25b0a
 +  void scanBackClusters(UText *text, int32_t textStart, int32_t& start) const;
5a25b0a
 +  void scanFwdClusters(UText *text, int32_t textEnd, int32_t& end) const;
5a25b0a
- 
5a25b0a
++
5a25b0a
   public:
5a25b0a
  
5a25b0a
-@@ -83,7 +144,7 @@
5a25b0a
+   /**
5a25b0a
+-   * 

Constructor

5a25b0a
++   * 

Default constructor.

5a25b0a
++   *
5a25b0a
+    */
5a25b0a
+   DictionaryBreakEngine();
5a25b0a
+ 
5a25b0a
+   /**
5a25b0a
++   * 

Constructor with break types.

5a25b0a
++   */
5a25b0a
++  explicit DictionaryBreakEngine(uint32_t breakTypes);
5a25b0a
++
5a25b0a
++  /**
5a25b0a
+    * 

Virtual destructor.

5a25b0a
+    */
5a25b0a
+   virtual ~DictionaryBreakEngine();
5a25b0a
+@@ -68,7 +139,7 @@
5a25b0a
     * 

Find any breaks within a run in the supplied text.

5a25b0a
     *
5a25b0a
     * @param text A UText representing the text. The iterator is left at
5a25b0a
@@ -763,7 +765,7 @@ diff -ur icu.org/source/common/dictbe.h icu/source/common/dictbe.h
5a25b0a
     * that starts from the first character in the range.
5a25b0a
     * @param startPos The start of the run within the supplied text.
5a25b0a
     * @param endPos The end of the run within the supplied text.
5a25b0a
-@@ -245,118 +306,120 @@
5a25b0a
+@@ -218,118 +289,120 @@
5a25b0a
  
5a25b0a
  };
5a25b0a
  
5a25b0a
@@ -997,8 +999,8 @@ diff -ur icu.org/source/common/dictbe.h icu/source/common/dictbe.h
5a25b0a
  
5a25b0a
  /*******************************************************************
5a25b0a
 diff -ur icu.org/source/common/dictionarydata.cpp icu/source/common/dictionarydata.cpp
5a25b0a
---- icu.org/source/common/dictionarydata.cpp	2017-01-20 01:20:31.000000000 +0100
5a25b0a
-+++ icu/source/common/dictionarydata.cpp	2017-04-21 23:14:23.846894372 +0200
5a25b0a
+--- icu.org/source/common/dictionarydata.cpp	2018-03-26 15:38:30.000000000 +0200
5a25b0a
++++ icu/source/common/dictionarydata.cpp	2018-04-17 14:04:50.775567214 +0200
5a25b0a
 @@ -44,7 +44,7 @@
5a25b0a
  
5a25b0a
  int32_t UCharsDictionaryMatcher::matches(UText *text, int32_t maxLength, int32_t limit,
5a25b0a
@@ -1046,8 +1048,8 @@ diff -ur icu.org/source/common/dictionarydata.cpp icu/source/common/dictionaryda
5a25b0a
                  if (values != NULL) {
5a25b0a
                      values[wordCount] = bt.getValue();
5a25b0a
 diff -ur icu.org/source/common/dictionarydata.h icu/source/common/dictionarydata.h
5a25b0a
---- icu.org/source/common/dictionarydata.h	2017-01-20 01:20:31.000000000 +0100
5a25b0a
-+++ icu/source/common/dictionarydata.h	2017-04-21 23:14:23.846894372 +0200
5a25b0a
+--- icu.org/source/common/dictionarydata.h	2018-03-26 15:38:30.000000000 +0200
5a25b0a
++++ icu/source/common/dictionarydata.h	2018-04-17 14:04:50.775567214 +0200
5a25b0a
 @@ -21,6 +21,7 @@
5a25b0a
  #include "unicode/utext.h"
5a25b0a
  #include "unicode/udata.h"
5a25b0a
@@ -1084,8 +1086,8 @@ diff -ur icu.org/source/common/dictionarydata.h icu/source/common/dictionarydata
5a25b0a
  private:
5a25b0a
      UChar32 transform(UChar32 c) const;
5a25b0a
 diff -ur icu.org/source/data/Makefile.in icu/source/data/Makefile.in
5a25b0a
---- icu.org/source/data/Makefile.in	2017-04-21 23:13:03.248087545 +0200
5a25b0a
-+++ icu/source/data/Makefile.in	2017-04-21 23:14:23.846894372 +0200
5a25b0a
+--- icu.org/source/data/Makefile.in	2018-04-17 12:28:37.098707466 +0200
5a25b0a
++++ icu/source/data/Makefile.in	2018-04-17 14:04:50.775567214 +0200
5a25b0a
 @@ -183,7 +183,7 @@
5a25b0a
  endif
5a25b0a
  endif
5a25b0a
diff --git a/external/icu/icu4c-ubsan.patch.1 b/external/icu/icu4c-ubsan.patch.1
5a25b0a
deleted file mode 100644
5a25b0a
index 9f6aa3fbc9f8..000000000000
5a25b0a
--- a/external/icu/icu4c-ubsan.patch.1
5a25b0a
+++ /dev/null
5a25b0a
@@ -1,91 +0,0 @@
5a25b0a
-diff -ur icu.org/source/common/rbbidata.h icu/source/common/rbbidata.h
5a25b0a
---- icu.org/source/common/rbbidata.h	2017-02-03 19:57:23.000000000 +0100
5a25b0a
-+++ icu/source/common/rbbidata.h	2017-04-21 22:46:25.371651160 +0200
5a25b0a
-@@ -115,7 +115,7 @@
5a25b0a
-                                     /*     StatusTable of the set of matching             */
5a25b0a
-                                     /*     tags (rule status values)                      */
5a25b0a
-     int16_t          fReserved;
5a25b0a
--    uint16_t         fNextState[2]; /*  Next State, indexed by char category.             */
5a25b0a
-+    uint16_t         fNextState[1]; /*  Next State, indexed by char category.             */
5a25b0a
-                                     /*  This array does not have two elements             */
5a25b0a
-                                     /*    Array Size is actually fData->fHeader->fCatCount         */
5a25b0a
-                                     /*    CAUTION:  see RBBITableBuilder::getTableSize()  */
5a25b0a
-@@ -128,7 +128,7 @@
5a25b0a
-     uint32_t         fRowLen;       /*  Length of a state table row, in bytes.            */
5a25b0a
-     uint32_t         fFlags;        /*  Option Flags for this state table                 */
5a25b0a
-     uint32_t         fReserved;     /*  reserved                                          */
5a25b0a
--    char             fTableData[4]; /*  First RBBIStateTableRow begins here.              */
5a25b0a
-+    char             fTableData[1]; /*  First RBBIStateTableRow begins here.              */
5a25b0a
-                                     /*    (making it char[] simplifies ugly address       */
5a25b0a
-                                     /*     arithmetic for indexing variable length rows.) */
5a25b0a
- };
5a25b0a
-diff -ur icu.org/source/common/rbbitblb.cpp icu/source/common/rbbitblb.cpp
5a25b0a
---- icu.org/source/common/rbbitblb.cpp	2017-01-20 01:20:31.000000000 +0100
5a25b0a
-+++ icu/source/common/rbbitblb.cpp	2017-04-21 22:46:25.373651159 +0200
5a25b0a
-@@ -1095,15 +1095,15 @@
5a25b0a
-         return 0;
5a25b0a
-     }
5a25b0a
- 
5a25b0a
--    size    = sizeof(RBBIStateTable) - 4;    // The header, with no rows to the table.
5a25b0a
-+    size    = offsetof(RBBIStateTable, fTableData);    // The header, with no rows to the table.
5a25b0a
- 
5a25b0a
-     numRows = fDStates->size();
5a25b0a
-     numCols = fRB->fSetBuilder->getNumCharCategories();
5a25b0a
- 
5a25b0a
--    //  Note  The declaration of RBBIStateTableRow is for a table of two columns.
5a25b0a
--    //        Therefore we subtract two from numCols when determining
5a25b0a
-+    //  Note  The declaration of RBBIStateTableRow is for a table of one columns.
5a25b0a
-+    //        Therefore we subtract one from numCols when determining
5a25b0a
-     //        how much storage to add to a row for the total columns.
5a25b0a
--    rowSize = sizeof(RBBIStateTableRow) + sizeof(uint16_t)*(numCols-2);
5a25b0a
-+    rowSize = sizeof(RBBIStateTableRow) + sizeof(uint16_t)*(numCols-1);
5a25b0a
-     size   += numRows * rowSize;
5a25b0a
-     return size;
5a25b0a
- }
5a25b0a
-@@ -1133,7 +1133,7 @@
5a25b0a
-     }
5a25b0a
- 
5a25b0a
-     table->fRowLen    = sizeof(RBBIStateTableRow) +
5a25b0a
--                            sizeof(uint16_t) * (fRB->fSetBuilder->getNumCharCategories() - 2);
5a25b0a
-+                            sizeof(uint16_t) * (fRB->fSetBuilder->getNumCharCategories() - 1);
5a25b0a
-     table->fNumStates = fDStates->size();
5a25b0a
-     table->fFlags     = 0;
5a25b0a
-     if (fRB->fLookAheadHardBreak) {
5a25b0a
-diff -ur icu.org/source/common/ubidiimp.h icu/source/common/ubidiimp.h
5a25b0a
---- icu.org/source/common/ubidiimp.h	2017-02-03 19:57:23.000000000 +0100
5a25b0a
-+++ icu/source/common/ubidiimp.h	2017-04-21 22:46:25.374651159 +0200
5a25b0a
-@@ -198,8 +198,8 @@
5a25b0a
- /* in a Run, logicalStart will get this bit set if the run level is odd */
5a25b0a
- #define INDEX_ODD_BIT (1UL<<31)
5a25b0a
- 
5a25b0a
--#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((int32_t)(level)<<31))
5a25b0a
--#define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((int32_t)(level)<<31))
5a25b0a
-+#define MAKE_INDEX_ODD_PAIR(index, level) ((index)|((uint32_t)(level)<<31))
5a25b0a
-+#define ADD_ODD_BIT_FROM_LEVEL(x, level)  ((x)|=((uint32_t)(level)<<31))
5a25b0a
- #define REMOVE_ODD_BIT(x)                 ((x)&=~INDEX_ODD_BIT)
5a25b0a
- 
5a25b0a
- #define GET_INDEX(x)   ((x)&~INDEX_ODD_BIT)
5a25b0a
-diff -ur icu.org/source/common/ucmndata.cpp icu/source/common/ucmndata.cpp
5a25b0a
---- icu.org/source/common/ucmndata.cpp	2017-03-08 16:34:47.000000000 +0100
5a25b0a
-+++ icu/source/common/ucmndata.cpp	2017-04-21 22:46:25.376651159 +0200
5a25b0a
-@@ -77,7 +77,7 @@
5a25b0a
- typedef struct  {
5a25b0a
-     uint32_t          count;
5a25b0a
-     uint32_t          reserved;
5a25b0a
--    PointerTOCEntry   entry[2];   /* Actual size is from count. */
5a25b0a
-+    PointerTOCEntry   entry[1];   /* Actual size is from count. */
5a25b0a
- }  PointerTOC;
5a25b0a
- 
5a25b0a
- 
5a25b0a
-diff -ur icu.org/source/common/ucmndata.h icu/source/common/ucmndata.h
5a25b0a
---- icu.org/source/common/ucmndata.h	2017-01-20 01:20:31.000000000 +0100
5a25b0a
-+++ icu/source/common/ucmndata.h	2017-04-21 22:46:25.377651159 +0200
5a25b0a
-@@ -52,7 +52,7 @@
5a25b0a
- 
5a25b0a
- typedef struct {
5a25b0a
-     uint32_t count;
5a25b0a
--    UDataOffsetTOCEntry entry[2];    /* Actual size of array is from count. */
5a25b0a
-+    UDataOffsetTOCEntry entry[1];    /* Actual size of array is from count. */
5a25b0a
- } UDataOffsetTOC;
5a25b0a
- 
5a25b0a
- /**
5a25b0a
5a25b0a
--------------erAck-patch-parts--
5a25b0a
5a25b0a