From 73b01ea5f4c9e6118114c993fc21bd653ef73804 Mon Sep 17 00:00:00 2001
From: Nikita Zheleztsov <n.zheleztsov@proton.me>
Date: Tue, 14 Feb 2023 01:51:45 +0300
Subject: [PATCH] icu: fix NULL dereference in `enumEitherTrie`

According to the business logic and assertions `idx` and `data32`
variables cannot be equal to NULL at the same time. However, we
cannot rely on assertions.

Let's check that explicitly. If this situation occurs somehow
the function exits as we cannot recover from this situation: we
don't have sources, from which values for enumeration can be taken.
Moreover, continuing of the code execution is such situation may
lead to accessing NULL if `c<limit`.

Closes tarantool/security#59

NO_CHANGELOG=<security fix>
NO_DOC=<security fix>
NO_TEST=<third-party security fix>
---
 .../cmake/AddDependencyProjects.cmake         |  1 +
 .../patches/icu-tarantool-security-59.patch   | 21 +++++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 static-build/patches/icu-tarantool-security-59.patch

diff --git a/static-build/cmake/AddDependencyProjects.cmake b/static-build/cmake/AddDependencyProjects.cmake
index d52dae7a35..a5f38fa227 100644
--- a/static-build/cmake/AddDependencyProjects.cmake
+++ b/static-build/cmake/AddDependencyProjects.cmake
@@ -115,6 +115,7 @@ ExternalProject_Add(icu
         cat <BINARY_DIR>/uconfig.h.prepend <INSTALL_DIR>/include/unicode/uconfig.h >> <BINARY_DIR>/uconfig.h &&
         ${CMAKE_COMMAND} -E copy_if_different <BINARY_DIR>/uconfig.h <INSTALL_DIR>/include/unicode/uconfig.h
     PATCH_COMMAND patch -d <SOURCE_DIR> -p1 -i "${PATCHES_DIR}/icu-tarantool-security-45.patch"
+    COMMAND       patch -d <SOURCE_DIR> -p1 -i "${PATCHES_DIR}/icu-tarantool-security-59.patch"
 )
 set(TARANTOOL_DEPENDS icu ${TARANTOOL_DEPENDS})
 
diff --git a/static-build/patches/icu-tarantool-security-59.patch b/static-build/patches/icu-tarantool-security-59.patch
new file mode 100644
index 0000000000..f41ec006ad
--- /dev/null
+++ b/static-build/patches/icu-tarantool-security-59.patch
@@ -0,0 +1,21 @@
+diff --git a/source/common/utrie2.cpp b/source/common/utrie2.cpp
+index 24ef578..359952a 100644
+--- a/source/common/utrie2.cpp
++++ b/source/common/utrie2.cpp
+@@ -574,7 +574,15 @@ enumEitherTrie(const UTrie2 *trie,
+                     c+=UTRIE2_DATA_BLOCK_LENGTH;
+                 } else {
+                     for(j=0; j<UTRIE2_DATA_BLOCK_LENGTH; ++j) {
+-                        value=enumValue(context, data32!=NULL ? data32[block+j] : idx[block+j]);
++                        if (data32!=NULL) {
++                            value=enumValue(context, data32[block+j]);
++                        } else if (idx!=NULL) {
++                            value=enumValue(context, idx[block+j]);
++                        } else {
++                            /* data32 and idx are not supposed to be NULL at the same time */
++                            U_ASSERT(false);
++                            return;
++                        }
+                         if(value!=prevValue) {
+                             if(prev<c && !enumRange(context, prev, c-1, prevValue)) {
+                                 return;
-- 
GitLab