Skip to content

Commit

Permalink
Catch an unchecked exception which may be thrown by Strings.repeat()
Browse files Browse the repository at this point in the history
To provide a nicer error message for the user. Otherwise, we'd get an
UncheckedEvalException without a Starlark stack trace.

RELNOTES: None.
PiperOrigin-RevId: 384559307
  • Loading branch information
tetromino authored and copybara-github committed Jul 13, 2021
1 parent d409207 commit 1bd7812
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/main/java/net/starlark/java/eval/EvalUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,15 @@ private static int compare(Object x, Object y) throws EvalException {

private static String repeatString(String s, StarlarkInt in) throws EvalException {
int n = in.toInt("repeat");
// TODO(adonovan): reject unreasonably large n.
return n <= 0 ? "" : Strings.repeat(s, n);
if (n <= 0) {
return "";
} else if ((long) s.length() * (long) n > Integer.MAX_VALUE) {
// Would exceed max length of a java String (and would cause an undocumented
// ArrayIndexOutOfBoundsException to be thrown in Strings.repeat()).
throw Starlark.errorf("excessive repeat (%d * %d characters)", s.length(), n);
} else {
return Strings.repeat(s, n);
}
}

/** Evaluates a unary operation. */
Expand Down
1 change: 1 addition & 0 deletions src/test/java/net/starlark/java/eval/testdata/list.star
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ assert_eq(3 * [1, 2, 3], [1, 2, 3, 1, 2, 3, 1, 2, 3])
assert_eq([1, 2, 3] * -1, [])
assert_eq([1, 2, 3] * 0, [])
assert_fails(lambda: [1] * (1 << 35), "got 34359738368 for repeat, want value in signed 32-bit range")
assert_fails(lambda: [1, 2, 3] * (1 << 30), "excessive repeat \\(3 \\* 1073741824 elements\\)")
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,4 @@ assert_eq(3 * "abc", "abcabcabc")
assert_eq("abc" * 0, "")
assert_eq("abc" * -1, "")
assert_fails(lambda: "abc" * (1 << 35), "got 34359738368 for repeat, want value in signed 32-bit range")
assert_fails(lambda: "abc" * (1 << 30), "excessive repeat \\(3 \\* 1073741824 characters\\)")

0 comments on commit 1bd7812

Please sign in to comment.