Bug fixed: When string?split(separator) is called with "" as the argument, the string will be split to characters now. Earlier it has thrown an IllegalArgumentException (unless the r flag was specified).
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/cb5f3276 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/cb5f3276 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/cb5f3276 Branch: refs/heads/2.3 Commit: cb5f3276ca3a3c45cfd6938921297030a0aa4b5f Parents: 470971a Author: ddekany <ddek...@apache.org> Authored: Tue Mar 20 18:57:52 2018 +0100 Committer: ddekany <ddek...@apache.org> Committed: Tue Mar 20 18:57:52 2018 +0100 ---------------------------------------------------------------------- .../core/BuiltInsForStringsBasic.java | 2 +- .../freemarker/template/utility/StringUtil.java | 55 ++++++++++++-------- src/manual/en_US/book.xml | 13 +++++ 3 files changed, 47 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cb5f3276/src/main/java/freemarker/core/BuiltInsForStringsBasic.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java index abb3530..27a6212 100644 --- a/src/main/java/freemarker/core/BuiltInsForStringsBasic.java +++ b/src/main/java/freemarker/core/BuiltInsForStringsBasic.java @@ -536,7 +536,7 @@ class BuiltInsForStringsBasic { long flags = argCnt > 1 ? RegexpHelper.parseFlagString((String) args.get(1)) : 0; String[] result = null; if ((flags & RegexpHelper.RE_FLAG_REGEXP) == 0) { - RegexpHelper.checkNonRegexpFlags("split", flags); + RegexpHelper.checkNonRegexpFlags(key, flags); result = StringUtil.split(s, splitString, (flags & RegexpHelper.RE_FLAG_CASE_INSENSITIVE) != 0); } else { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cb5f3276/src/main/java/freemarker/template/utility/StringUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/StringUtil.java b/src/main/java/freemarker/template/utility/StringUtil.java index a5156aa..1238dd9 100644 --- a/src/main/java/freemarker/template/utility/StringUtil.java +++ b/src/main/java/freemarker/template/utility/StringUtil.java @@ -739,34 +739,45 @@ public class StringUtil { /** * Splits a string at the specified string. + * + * @param sep + * The string that separates the items of the resulting array. Since 2.3.28, if this is 0 length, then + * each character will be a separate item in the array. */ public static String[] split(String s, String sep, boolean caseInsensitive) { - String splitString = caseInsensitive ? sep.toLowerCase() : sep; - String input = caseInsensitive ? s.toLowerCase() : s; - int i, b, e; - int cnt; - String res[]; - int ln = s.length(); - int sln = sep.length(); + int sepLn = sep.length(); - if (sln == 0) throw new IllegalArgumentException( - "The separator string has 0 length"); + String convertedS = caseInsensitive ? s.toLowerCase() : s; + int sLn = s.length(); + + if (sepLn == 0) { + String[] res = new String[sLn]; + for (int i = 0; i < sLn; i++) { + res[i] = String.valueOf(s.charAt(i)); + } + return res; + } - i = 0; - cnt = 1; - while ((i = input.indexOf(splitString, i)) != -1) { - cnt++; - i += sln; + String splitString = caseInsensitive ? sep.toLowerCase() : sep; + String res[]; + + { + int next = 0; + int count = 1; + while ((next = convertedS.indexOf(splitString, next)) != -1) { + count++; + next += sepLn; + } + res = new String[count]; } - res = new String[cnt]; - i = 0; - b = 0; - while (b <= ln) { - e = input.indexOf(splitString, b); - if (e == -1) e = ln; - res[i++] = s.substring(b, e); - b = e + sln; + int dst = 0; + int next = 0; + while (next <= sLn) { + int end = convertedS.indexOf(splitString, next); + if (end == -1) end = sLn; + res[dst++] = s.substring(next, end); + next = end + sepLn; } return res; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/cb5f3276/src/manual/en_US/book.xml ---------------------------------------------------------------------- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index 349319c..eb4470f 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -14441,6 +14441,10 @@ foobar</programlisting> <literal>?split(",", "r")</literal> in the last example the last <literal>""</literal> would be missing from the output.</para> + <para>If the 1st parameter is an empty string, the string will be + split to characters (since FreeMarker 2.3.28 - earlier this has only + worked with the <literal>r</literal> flag).</para> + <note> <para>To check if a strings ends with something and append it otherwise, use <link linkend="ref_builtin_ensure_ends_with">the @@ -27635,6 +27639,15 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting> evaluated in the context of the called macro or function.)</para> </listitem> + + <listitem> + <para>Bug fixed: When + <literal><replaceable>string</replaceable>?split(<replaceable>separator</replaceable>)</literal> + is called with <literal>""</literal> as the argument, the string + will be split to characters now. Earlier it has thrown an + <literal>IllegalArgumentException</literal> (unless the + <literal>r</literal> flag was specified).</para> + </listitem> </itemizedlist> </section>