Skip to content

Commit e04cad4

Browse files
committed
StringRenderer: fix bug with .substring() vs code points...
RFC 6570 section 2.1 defines a character as a Unicode character; which means code points outside the BMP are possible. In which case the prefix modifier must return the matching number of code points, not the number of Java chars. .substring() is therefore not suitable, neither is .length().
1 parent b0d1d7e commit e04cad4

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

src/main/java/com/github/fge/uritemplate/render/StringRenderer.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,19 @@ private String doRender(final VariableSpec varspec, final String value)
6161
ret += '=';
6262
}
6363
// Account for a prefix, if any. Note: explode modifier is ignored.
64-
final int len = value.length();
64+
final int len = value.codePointCount(0, value.length());
6565
final int prefixLen = varspec.getPrefixLength();
6666
final String val = prefixLen == -1 ? value
67-
: value.substring(0, Math.min(len, prefixLen));
67+
: nFirstCodePoints(value, Math.min(len, prefixLen));
6868
ret += pctEncode(val);
6969
return ret;
7070
}
71+
72+
private static String nFirstCodePoints(final String s, final int n)
73+
{
74+
int realIndex = n;
75+
while (s.codePointCount(0, realIndex) != n)
76+
realIndex++;
77+
return s.substring(0, realIndex);
78+
}
7179
}

src/test/resources/expand/strings.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
"vars": {
33
"var": "value",
44
"hello": "Hello World!",
5-
"empty": ""
5+
"empty": "",
6+
"poo": "\ud83d\udca9 is a pile of poo"
67
},
78
"tests": {
9+
"{poo:4}": "%F0%9F%92%A9%20is",
810
"{var}": "value",
911
"{+var}": "value",
1012
"{.var}": ".value",

0 commit comments

Comments
 (0)