summaryrefslogtreecommitdiff
path: root/dev-lang/php/files/php-7.0.33-intl-icu-memory-corruption.patch
blob: e6e7f5917c5bcc440c94ee49abd69a1dc4dd6218 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Based on the following upstream commits:

https://github.com/php/php-src/commit/45a05f38410d4a67c8c83c09906e2cfb42fc6e4c
https://github.com/php/php-src/commit/534684d1042978f3c21caf9b665a7aca27f3f325

--- a/ext/intl/msgformat/msgformat_helpers.cpp
+++ b/ext/intl/msgformat/msgformat_helpers.cpp
@@ -27,6 +27,7 @@
 #include <unicode/timezone.h>
 #include <unicode/datefmt.h>
 #include <unicode/calendar.h>
+#include <unicode/strenum.h>
 
 #include <vector>
 
@@ -45,6 +46,7 @@ extern "C" {
 
 #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
 #define HAS_MESSAGE_PATTERN 1
+#define HAS_MISALLOCATE_MEMORY_BUG 1
 #endif
 
 U_NAMESPACE_BEGIN
@@ -345,6 +347,26 @@ static void umsg_set_timezone(MessageFormatter_object *mfo,
 		return; /* already done */
 	}
 
+#ifdef HAS_MISALLOCATE_MEMORY_BUG
+	/* There is a bug in ICU which prevents MessageFormatter::getFormats()
+	   to handle more than 10 formats correctly. The enumerator could be
+	   used to walk through the present formatters using getFormat(), which
+	   however seems to provide just a readonly access. This workaround
+	   prevents crash when there are > 10 formats but doesn't set any error.
+	   As a result, only DateFormatters with > 10 subformats are affected.
+	   This workaround should be ifdef'd out, when the bug has been fixed
+	   in ICU. */
+	icu::StringEnumeration* fnames = mf->getFormatNames(err.code);
+	if (!fnames || U_FAILURE(err.code)) {
+		return;
+	}
+	count = fnames->count(err.code);
+	delete fnames;
+	if (count > 10) {
+		return;
+	}
+#endif
+
 	formats = mf->getFormats(count);
 
 	if (formats == NULL) {
--- /dev/null
+++ b/ext/intl/tests/bug74484_MessageFormatter.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #74484 MessageFormatter::formatMessage memory corruption with 11+ named placeholder
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+	die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+	die('skip for ICU 4.8+');
+?>
+--FILE--
+<?php
+$text = "{a} {b} {c} {d} {e} {f} {g} {h} {i} {j} {k} {l}";
+
+$vars = array(
+  'a' => 1,
+  'b' => 2,
+  'c' => 3,
+  'd' => 4,
+  'e' => 5,
+  'f' => 6,
+  'g' => 7,
+  'h' => 8,
+  'i' => 9,
+  'j' => 10,
+  'k' => 11,
+  'l' => 12
+);
+
+var_dump(MessageFormatter::formatMessage('en_US', $text, $vars));
+
+?>
+==DONE==
+--EXPECT--
+string(26) "1 2 3 4 5 6 7 8 9 10 11 12"
+==DONE==
-- 
2.19.2