Skip to content

Commit f5f460f

Browse files
lkotuladahlerlend
authored andcommitted
BUG#28125030 - C/JAVA ASYNCHRONOUS XPLUGIN TESTS CAUSES CRASH IN MYSQL SERVER 8.0.12
Description =========== Executing multithread test that uses an X Expression with cast operator, causes a crash. The problem concerns Icu::RegexMatcher, which is neither thread-safe nor re-entrant. Fix === The fix allocates ice::RegexMatcher per thread. RB: 19822 Reviewed-by: Tomasz Stepniak <[email protected]> Reviewed-by: Grzegorz Szwarc <[email protected]>
1 parent f7ea540 commit f5f460f

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

plugin/x/src/xpl_regex.cc

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,43 @@
2222

2323
#include "plugin/x/src/xpl_regex.h"
2424

25+
#include <memory>
26+
2527
#include "include/my_dbug.h"
2628

2729
namespace xpl {
2830

2931
Regex::Regex(const char *const pattern)
3032
: m_status{U_ZERO_ERROR},
31-
m_re{icu::UnicodeString::fromUTF8(pattern), UREGEX_CASE_INSENSITIVE,
32-
m_status} {
33+
m_pattern{icu::RegexPattern::compile(
34+
icu::UnicodeString::fromUTF8(pattern), UREGEX_CASE_INSENSITIVE,
35+
m_parse_error, m_status)} {
3336
DBUG_ASSERT(U_SUCCESS(m_status));
3437
}
3538

3639
bool xpl::Regex::match(const char *value) const {
37-
return U_SUCCESS(m_status) &&
38-
m_re.reset(icu::UnicodeString::fromUTF8(value)).find(m_status);
40+
if (!U_SUCCESS(m_status)) return false;
41+
42+
UErrorCode match_status{U_ZERO_ERROR};
43+
44+
/* Initializing RegexMatcher object with RegexPattern
45+
* can by done only by calling an RegexPattern method
46+
* that returns RegexMatcher pointer.
47+
*
48+
* RegexMatcher is not reentrant thus we need create an
49+
* instance per thread or like in current solution,
50+
* instance per xpl::Regex::match call.
51+
*
52+
* Other possibility would be to create RegexMatcher on stack
53+
* and parse the text patter each time that xpl::Regex::match
54+
* is called.
55+
*/
56+
std::unique_ptr<icu::RegexMatcher> regexp{
57+
m_pattern->matcher(icu::UnicodeString::fromUTF8(value), match_status)};
58+
59+
if (!U_SUCCESS(match_status)) return false;
60+
61+
return regexp->find();
3962
}
4063

4164
} // namespace xpl

plugin/x/src/xpl_regex.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#ifndef PLUGIN_X_SRC_XPL_REGEX_H_
2424
#define PLUGIN_X_SRC_XPL_REGEX_H_
2525

26+
#include <memory>
27+
2628
#include "unicode/regex.h"
2729

2830
namespace xpl {
@@ -33,8 +35,18 @@ class Regex {
3335
bool match(const char *value) const;
3436

3537
private:
36-
mutable UErrorCode m_status;
37-
mutable icu::RegexMatcher m_re;
38+
UErrorCode m_status;
39+
UParseError m_parse_error;
40+
/* RegexPatter doesn't have public constructor
41+
* that allow to initialize the object directly
42+
* by the text patter. Only static method which
43+
* returns an object pointer allows initialization
44+
* text patter.
45+
*
46+
* We require here to have an smart-ptr/field
47+
* instead a object/field.
48+
*/
49+
std::unique_ptr<icu::RegexPattern> m_pattern;
3850
};
3951
} // namespace xpl
4052

0 commit comments

Comments
 (0)