Skip to content

Commit 1c93301

Browse files
Re-enable handling of unicode strings in std.base64 (#492) (#493)
This is an artificial limitation in go-jsonnet and we are not bound by it. We are perfectly capable of encoding and decoding unicode strings.
1 parent abc0f42 commit 1c93301

7 files changed

Lines changed: 30 additions & 19 deletions

File tree

sjsonnet/src/sjsonnet/Std.scala

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,24 +1661,27 @@ class Std(
16611661
rec(Materializer(value)(ev)).render
16621662
},
16631663
builtin("base64", "input") { (_, _, input: Val) =>
1664-
val b: Array[Int] = input match {
1665-
case Val.Str(_, value) => value.indices.map(value.codePointAt).toArray
1666-
case arr: Val.Arr =>
1667-
if (!arr.forall(_.isInstanceOf[Val.Num])) {
1668-
Error.fail("Expected an array of numbers or a string")
1664+
input match {
1665+
case Val.Str(_, value) =>
1666+
Base64.getEncoder.encodeToString(value.getBytes("UTF-8"))
1667+
case arr: Val.Arr =>
1668+
val byteArr = new Array[Byte](arr.length)
1669+
for (i <- 0 until arr.length) {
1670+
val v = arr.force(i)
1671+
if (!v.isInstanceOf[Val.Num]) {
1672+
Error.fail(f"Expected an array of numbers, got a ${v.prettyName} at position $i")
1673+
}
1674+
val vInt = v.asInt
1675+
if (vInt < 0 || vInt > 255) {
1676+
Error.fail(
1677+
f"Found an invalid codepoint value at position $i (must be 0 <= X <= 255), got $vInt"
1678+
)
1679+
}
1680+
byteArr(i) = vInt.toByte
16691681
}
1670-
arr.iterator.map(_.cast[Val.Num].asInt).toArray
1682+
Base64.getEncoder.encodeToString(byteArr)
16711683
case x => Error.fail("Cannot base64 encode " + x.prettyName)
16721684
}
1673-
1674-
for (i <- b) {
1675-
if (i < 0 || i > 255) {
1676-
Error.fail(
1677-
f"Found an invalid codepoint value in the ${input.prettyName} (must be 0 <= X <= 255), got $i"
1678-
)
1679-
}
1680-
}
1681-
Base64.getEncoder.encodeToString(b.map(_.toByte))
16821685
},
16831686
builtin("base64Decode", "str") { (_, _, str: String) =>
16841687
try {

sjsonnet/test/graalvm/run_test_suites.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ def test_all_files(self):
137137
"native7",
138138
"native_error",
139139
"native_panic",
140+
141+
# We support base64 of unicode strings
142+
"builtinBase64_string_high_codepoint",
140143
]
141144

142145
# Find all .jsonnet files in the test directory
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
sjsonnet.Error: Expected an array of numbers or a string
1+
sjsonnet.Error: Expected an array of numbers, got a string at position 1
22
at [std.base64].(builtinBase64_invalid_byte_array.jsonnet:1:11)
33

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
sjsonnet.Error: Found an invalid codepoint value in the array (must be 0 <= X <= 255), got -1
1+
sjsonnet.Error: Found an invalid codepoint value at position 1 (must be 0 <= X <= 255), got -1
22
at [std.base64].(builtinBase64_invalid_byte_array1.jsonnet:1:11)
33

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
sjsonnet.Error: Found an invalid codepoint value in the array (must be 0 <= X <= 255), got 256
1+
sjsonnet.Error: Found an invalid codepoint value at position 1 (must be 0 <= X <= 255), got 256
22
at [std.base64].(builtinBase64_invalid_byte_array2.jsonnet:1:11)
33

sjsonnet/test/src-js/sjsonnet/FileTests.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ object FileTests extends BaseFileTests {
1616
)
1717

1818
val goTestDataSkippedTests: Set[String] = Set(
19+
// We support base64 of unicode strings
20+
"builtinBase64_string_high_codepoint.jsonnet",
1921
"builtinSha1.jsonnet",
2022
"builtinSha256.jsonnet",
2123
"builtinSha3.jsonnet",

sjsonnet/test/src-jvm-native/sjsonnet/FileTests.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ object FileTests extends BaseFileTests {
1616
)
1717
else Set.empty[String]
1818

19-
val goTestDataSkippedTests: Set[String] = Set.empty
19+
val goTestDataSkippedTests: Set[String] = Set(
20+
// We support base64 of unicode strings
21+
"builtinBase64_string_high_codepoint.jsonnet"
22+
)
2023

2124
val tests: Tests = Tests {
2225
test("test_suite") - {

0 commit comments

Comments
 (0)