Fix String.padStart/padEnd (#1672)

Fixes the following two bugs:

* Pads to incorrect string length
* Does not append full code point
This commit is contained in:
Daniel Chao
2026-06-10 08:34:50 -07:00
committed by GitHub
parent 44f8706616
commit 1a1e1cfea9
3 changed files with 16 additions and 6 deletions
@@ -745,13 +745,12 @@ public final class StringNodes {
@TruffleBoundary @TruffleBoundary
@Specialization @Specialization
protected String eval(String self, long width, String ch) { protected String eval(String self, long width, String ch) {
var length = self.length(); var length = self.codePointCount(0, self.length());
if (length >= width) return self; if (length >= width) return self;
var result = new StringBuilder(VmSafeMath.toInt32(width)); var result = new StringBuilder(VmSafeMath.toInt32(width));
var c = ch.charAt(0);
for (var i = 0; i < width - length; i++) { for (var i = 0; i < width - length; i++) {
result.append(c); result.append(ch);
} }
result.append(self); result.append(self);
return result.toString(); return result.toString();
@@ -762,14 +761,13 @@ public final class StringNodes {
@TruffleBoundary @TruffleBoundary
@Specialization @Specialization
protected String eval(String self, long width, String ch) { protected String eval(String self, long width, String ch) {
var length = self.length(); var length = self.codePointCount(0, self.length());
if (length >= width) return self; if (length >= width) return self;
var result = new StringBuilder(VmSafeMath.toInt32(width)); var result = new StringBuilder(VmSafeMath.toInt32(width));
result.append(self); result.append(self);
var c = ch.charAt(0);
for (var i = 0; i < width - length; i++) { for (var i = 0; i < width - length; i++) {
result.append(c); result.append(ch);
} }
return result.toString(); return result.toString();
} }
@@ -452,6 +452,9 @@ examples {
str1.padStart(10, " ") str1.padStart(10, " ")
module.catch(() -> str1.padStart(10, "")) module.catch(() -> str1.padStart(10, ""))
module.catch(() -> str1.padStart(10, "aa")) module.catch(() -> str1.padStart(10, "aa"))
"🙃".padStart(5, "h")
"🙃".padStart(5, "🏀")
"hi".padStart(5, "🏀")
} }
["padEnd()"] { ["padEnd()"] {
@@ -463,6 +466,9 @@ examples {
str1.padEnd(10, " ") str1.padEnd(10, " ")
module.catch(() -> str1.padEnd(10, "")) module.catch(() -> str1.padEnd(10, ""))
module.catch(() -> str1.padEnd(10, "aa")) module.catch(() -> str1.padEnd(10, "aa"))
"🙃".padEnd(5, "h")
"🙃".padEnd(5, "🏀")
"hi".padEnd(5, "🏀")
} }
["toBooleanOrNull()"] { ["toBooleanOrNull()"] {
@@ -386,6 +386,9 @@ examples {
" abcdefg" " abcdefg"
"Type constraint `length == 1` violated. Value: \"\"" "Type constraint `length == 1` violated. Value: \"\""
"Type constraint `length == 1` violated. Value: \"aa\"" "Type constraint `length == 1` violated. Value: \"aa\""
"hhhh🙃"
"🏀🏀🏀🏀🙃"
"🏀🏀🏀hi"
} }
["padEnd()"] { ["padEnd()"] {
"" ""
@@ -396,6 +399,9 @@ examples {
"abcdefg " "abcdefg "
"Type constraint `length == 1` violated. Value: \"\"" "Type constraint `length == 1` violated. Value: \"\""
"Type constraint `length == 1` violated. Value: \"aa\"" "Type constraint `length == 1` violated. Value: \"aa\""
"🙃hhhh"
"🙃🏀🏀🏀🏀"
"hi🏀🏀🏀"
} }
["toBooleanOrNull()"] { ["toBooleanOrNull()"] {
true true