Skip to content

Commit

Permalink
ICU-22798 Avoid stack overflow by return error.
Browse files Browse the repository at this point in the history
See #3035
  • Loading branch information
FrankYFTang authored and rp9-next committed Jun 14, 2024
1 parent b82291f commit 697cb14
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 1 deletion.
2 changes: 1 addition & 1 deletion icu4c/source/common/messagepattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ MessagePattern::parseMessage(int32_t index, int32_t msgStartLength,
if(U_FAILURE(errorCode)) {
return 0;
}
if(nestingLevel>Part::MAX_VALUE) {
if(nestingLevel>Part::MAX_NESTED_LEVELS) {
errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions icu4c/source/common/unicode/messagepattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ class U_COMMON_API MessagePattern : public UObject {

static const int32_t MAX_LENGTH=0xffff;
static const int32_t MAX_VALUE=0x7fff;
static const int32_t MAX_NESTED_LEVELS=0x03ff;

// Some fields are not final because they are modified during pattern parsing.
// After pattern parsing, the parts are effectively immutable.
Expand Down
18 changes: 18 additions & 0 deletions icu4c/source/test/intltest/msfmrgts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ MessageFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const ch
TESTCASE_AUTO(TestChoicePatternQuote);
TESTCASE_AUTO(Test4112104);
TESTCASE_AUTO(TestICU12584);
TESTCASE_AUTO(TestICU22798);
TESTCASE_AUTO(TestAPI);
TESTCASE_AUTO_END;
}
Expand Down Expand Up @@ -1013,6 +1014,23 @@ void MessageFormatRegressionTest::TestICU12584() {
inner_msg.getFormats(count);
assertEquals("Inner placeholder match", 3, count);
}
void MessageFormatRegressionTest::TestICU22798() {
// Test deep nested choice will not cause stack overflow but return error
// instead.
UErrorCode status = U_ZERO_ERROR;
UnicodeString pattern;
constexpr static int testNestedLevel = 30000;
for (int i = 0; i < testNestedLevel; i++) {
pattern += u"A{0,choice,0#";
}
pattern += u"text";
for (int i = 0; i < testNestedLevel; i++) {
pattern += u"}a";
}
MessageFormat msg(pattern, status);
assertEquals("Deep nested choice should cause error but not crash",
U_INDEX_OUTOFBOUNDS_ERROR, status);
}

void MessageFormatRegressionTest::TestAPI() {
UErrorCode status = U_ZERO_ERROR;
Expand Down
1 change: 1 addition & 0 deletions icu4c/source/test/intltest/msfmrgts.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MessageFormatRegressionTest: public IntlTest {
void TestChoicePatternQuote();
void Test4112104();
void TestICU12584();
void TestICU22798();
void TestAPI();

protected:
Expand Down

0 comments on commit 697cb14

Please sign in to comment.