-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 17, 21
-
b09
-
generic
-
generic
-
Verified
Under the assumption that the intention of MessageFormat.toPattern() is to generate a pattern that can be later used to recreate the same `MessageFormat`, then there is a case where MessageFormat.toPattern() is generates the wrong pattern string.
The bug is that MessageFormat.toPattern()` (correctly) quotes plain text opening "{" brace characters in the pattern, it does not quote plain text closing "}" brace characters. This is a problem because the pattern parser interprets a closing "}" brace character as the end of a nested format string.
As a result, when going from MessageFormat -> Pattern String -> MessageFormat, it's possible for the format to change semantically. This is obviously a problem for (for example) tools that store and retrieve MessageFormat's as pattern strings for the purpose of i18n, etc.
Test case:
import java.text.MessageFormat;
public class MessageFormatBug {
public static void main(String[] args) {
String pattern1 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}";
MessageFormat format1 = new MessageFormat(pattern1);
String result1 = format1.format(new Object[] { 0, 5 });
String pattern2 = format1.toPattern();
MessageFormat format2 = new MessageFormat(pattern2);
String result2 = format2.format(new Object[] { 0, 5 });
System.out.println(String.format("pattern1 = \"%s\"", pattern1));
System.out.println(String.format("pattern2 = \"%s\"", pattern2));
System.out.println(String.format("result1 = \"%s\"", result1));
System.out.println(String.format("result2 = \"%s\"", result2));
System.out.println("results are equal = " + result1.equals(result2));
}
}
Expected output:
pattern1 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}"
pattern2 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}"
result1 = "option A: 5"
result2 = "option A: 5"
results are equal = true
Actual output:
pattern1 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}"
pattern2 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}}}"
result1 = "option A: 5"
result2 = "option A: 5}"
results are equal = false
Reproducible in JDK 8, 11, 17, and 21.
The bug is that MessageFormat.toPattern()` (correctly) quotes plain text opening "{" brace characters in the pattern, it does not quote plain text closing "}" brace characters. This is a problem because the pattern parser interprets a closing "}" brace character as the end of a nested format string.
As a result, when going from MessageFormat -> Pattern String -> MessageFormat, it's possible for the format to change semantically. This is obviously a problem for (for example) tools that store and retrieve MessageFormat's as pattern strings for the purpose of i18n, etc.
Test case:
import java.text.MessageFormat;
public class MessageFormatBug {
public static void main(String[] args) {
String pattern1 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}";
MessageFormat format1 = new MessageFormat(pattern1);
String result1 = format1.format(new Object[] { 0, 5 });
String pattern2 = format1.toPattern();
MessageFormat format2 = new MessageFormat(pattern2);
String result2 = format2.format(new Object[] { 0, 5 });
System.out.println(String.format("pattern1 = \"%s\"", pattern1));
System.out.println(String.format("pattern2 = \"%s\"", pattern2));
System.out.println(String.format("result1 = \"%s\"", result1));
System.out.println(String.format("result2 = \"%s\"", result2));
System.out.println("results are equal = " + result1.equals(result2));
}
}
Expected output:
pattern1 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}"
pattern2 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}"
result1 = "option A: 5"
result2 = "option A: 5"
results are equal = true
Actual output:
pattern1 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}'}'}"
pattern2 = "{0,choice,0.0#option A: {1}|1.0#option B: {1}}}"
result1 = "option A: 5"
result2 = "option A: 5}"
results are equal = false
Reproducible in JDK 8, 11, 17, and 21.
- csr for
-
JDK-8324172 MessageFormat.toPattern() generates non-equivalent MessageFormat pattern
- Closed
- relates to
-
JDK-8324779 MessageFormat pattern quoting logic breaks with ChoiceFormat subformat
- Open