diff --git a/commons/src/main/java/com/itextpdf/commons/utils/MessageFormatUtil.java b/commons/src/main/java/com/itextpdf/commons/utils/MessageFormatUtil.java index 39d6e3ba41..8fc1586fec 100644 --- a/commons/src/main/java/com/itextpdf/commons/utils/MessageFormatUtil.java +++ b/commons/src/main/java/com/itextpdf/commons/utils/MessageFormatUtil.java @@ -61,82 +61,31 @@ private MessageFormatUtil() { * Indexed arguments can be referred with {index}, * to escape curly braces you have to double them. * + *

+ * Only basic escaping is allowed, single quotes in a set of curly braces are not supported and + * multiple escaped braces in a row are also not supported + * + *

+ * Allowed {{{0}}} + * Allowed '{0}' + * Allowed '{{{0}}}' + * + *

+ * Not allowed {{'{0}'}} + * Not allowed {{{{{0}}}}} + * * @param pattern to format * @param arguments arguments * * @return The formatted string */ public static String format(String pattern, Object... arguments) { - boolean mustClose = false; - StringBuilder result = new StringBuilder(pattern.length()); - int i = 0; - int n = pattern.length(); - while (i < n) { - char current = pattern.charAt(i); - switch (current) { - case '{': { - int curlyCount = 0; - int j; - for (j = i; j < n && pattern.charAt(j) == '{'; j++, curlyCount++) - ; - i += curlyCount - 1; - if (curlyCount > 1) { - if (!mustClose) { - result.append("'"); - } - while (curlyCount >= 2) { - result.append('{'); - curlyCount -= 2; - } - mustClose = true; - } - if (curlyCount == 1) { - if (mustClose) { - result.append('\''); - } - result.append('{'); - mustClose = false; - } - } - break; - case '}': { - int curlyCount = 0; - int j; - for (j = i; j < n && pattern.charAt(j) == '}'; j++, curlyCount++) - ; - i += curlyCount - 1; - if (curlyCount % 2 == 1) { - if (mustClose) { - result.append('\''); - } - result.append('}'); - mustClose = false; - } - if (curlyCount > 1) { - result.append("'"); - while (curlyCount >= 2) { - result.append('}'); - curlyCount -= 2; - } - mustClose = true; - } - } - break; - case '\'': - result.append("''"); - break; - default: - if (mustClose) { - result.append('\''); - mustClose = false; - } - result.append(current); - } - i++; - } - if (mustClose) { - result.append('\''); - } - return new MessageFormat(result.toString(), Locale.ROOT).format(arguments); + return new MessageFormat( + pattern.replace("'", "''") + .replace("{{{","'{'{" ) + .replace("}}}","}'}'" ) + .replace("{{","'{'" ) + .replace("}}","'}'" ) + ,Locale.ROOT).format(arguments); } } diff --git a/commons/src/test/java/com/itextpdf/commons/utils/MessageFormatUtilTest.java b/commons/src/test/java/com/itextpdf/commons/utils/MessageFormatUtilTest.java index d4a49a7c43..e1689d255b 100644 --- a/commons/src/test/java/com/itextpdf/commons/utils/MessageFormatUtilTest.java +++ b/commons/src/test/java/com/itextpdf/commons/utils/MessageFormatUtilTest.java @@ -45,14 +45,12 @@ public class MessageFormatUtilTest extends ExtendedITextTest { private String pattern; private Object[] arguments; - public MessageFormatUtilTest(Object expectedResult, Object pattern, Object arguments, Object name) { this.expectedResult = (String)expectedResult; this.pattern = (String)pattern; this.arguments = (Object[]) arguments; } - @Parameterized.Parameters(name = "{index}: {3} format: {1}; {0}") public static Iterable dataSource() { return Arrays.asList(new Object[][]{ @@ -60,12 +58,12 @@ public static Iterable dataSource() { {"Message with 'single quotes'", "Message with 'single quotes'", new Object[0],"test with single quotes"}, {"Message with ''doubled single quotes''", "Message with ''doubled single quotes''", new Object[0],"test with doubled single quotes"}, {"Message with {curly braces} and a parameter {I'm between curly braces too}", "Message with {{curly braces}} and a parameter {{{0}}}", new Object[]{"I'm between curly braces too"},"Test with curly braces"}, - {"Message with {{multiple curly braces}}", "Message with {{{{multiple curly braces}}}}", new Object[]{},"Test with multiple curly braces"}, - {"Message with {Value between brackets} and {{Value between double brackets}}", "Message with {{{0}}} and {{{{{1}}}}}", new Object[]{"Value between brackets", "Value between double brackets"},"Test with multiple curly braces"}, - {"Lets go wild 'value 1', {value 2}, '{value 3}', {'{value 4}'}", "Lets go wild '{0}', {{{1}}}, '{{{2}}}', {{'{{{3}}}'}}", new Object[]{"value 1", "value 2","value 3","value 4"},"Some of all"}, - {"{'{value}'}", "{{'{{{0}}}'}}", new Object[]{"value"},"Mix om multiple brackets and quotes 1"}, {"'{value}'", "'{{{0}}}'", new Object[]{"value"},"Mix om multiple brackets and quotes 1"}, - {"a '{'{123}'}''' b", "a '{{'{{{0}}}'}}''' b", new Object[]{123},"Mix om multiple brackets and quotes 1"}, + {"'value'", "'{0}'", new Object[]{"value"},"Mix of brackets and quotes"}, + {"{'0'}", "{{'0'}}", new Object[0],"Mix of multiple brackets and quotes 2"}, + {"single opening brace {0 test" , "single opening brace {{0 test", new Object[0],"Test single opening brace"}, + {"single closing brace 0} test", "single closing brace 0}} test", new Object[0],"Test single closing brace"}, + {"single opening + closing brace { test }", "single opening + closing brace {{ {0} }}", new Object[]{"test"},"Test single opening and closing brace"}, }); } @@ -73,5 +71,4 @@ public static Iterable dataSource() { public void testFormatting() { Assert.assertEquals(expectedResult, MessageFormatUtil.format(pattern, arguments)); } - } \ No newline at end of file