From e8bd3f4ff866336f71893b586ea54ea2c4d39e75 Mon Sep 17 00:00:00 2001 From: Wes McNamee Date: Sun, 15 Dec 2019 09:19:13 -0800 Subject: [PATCH] feat: improve stdlib base64 performance by 98.58%+ Implements std.base64 in native Go, improving performance benchmark old ns/op new ns/op delta Benchmark_Builtin_base64-16 10805730974 23158636 -99.79% Benchmark_Builtin_base64_bytearray-16 8682808704 123360964 -98.58% --- builtin-benchmarks/base64.jsonnet | 5 ++ builtin-benchmarks/base64_byte_array.jsonnet | 5 ++ builtins.go | 65 +++++++++++++++++++ builtins_benchmark_test.go | 8 +++ testdata/builtinBase64.golden | 1 + testdata/builtinBase64.jsonnet | 1 + testdata/builtinBase64_byte_array.golden | 1 + testdata/builtinBase64_byte_array.jsonnet | 1 + .../builtinBase64_invalid_byte_array.golden | 10 +++ .../builtinBase64_invalid_byte_array.jsonnet | 1 + .../builtinBase64_invalid_byte_array1.golden | 10 +++ .../builtinBase64_invalid_byte_array1.jsonnet | 1 + .../builtinBase64_invalid_byte_array2.golden | 10 +++ .../builtinBase64_invalid_byte_array2.jsonnet | 1 + .../builtinBase64_non_string_non_array.golden | 10 +++ ...builtinBase64_non_string_non_array.jsonnet | 1 + ...builtinBase64_string_high_codepoint.golden | 10 +++ ...uiltinBase64_string_high_codepoint.jsonnet | 1 + 18 files changed, 142 insertions(+) create mode 100644 builtin-benchmarks/base64.jsonnet create mode 100644 builtin-benchmarks/base64_byte_array.jsonnet create mode 100644 testdata/builtinBase64.golden create mode 100644 testdata/builtinBase64.jsonnet create mode 100644 testdata/builtinBase64_byte_array.golden create mode 100644 testdata/builtinBase64_byte_array.jsonnet create mode 100644 testdata/builtinBase64_invalid_byte_array.golden create mode 100644 testdata/builtinBase64_invalid_byte_array.jsonnet create mode 100644 testdata/builtinBase64_invalid_byte_array1.golden create mode 100644 testdata/builtinBase64_invalid_byte_array1.jsonnet create mode 100644 testdata/builtinBase64_invalid_byte_array2.golden create mode 100644 testdata/builtinBase64_invalid_byte_array2.jsonnet create mode 100644 testdata/builtinBase64_non_string_non_array.golden create mode 100644 testdata/builtinBase64_non_string_non_array.jsonnet create mode 100644 testdata/builtinBase64_string_high_codepoint.golden create mode 100644 testdata/builtinBase64_string_high_codepoint.jsonnet diff --git a/builtin-benchmarks/base64.jsonnet b/builtin-benchmarks/base64.jsonnet new file mode 100644 index 0000000..2a2bfa8 --- /dev/null +++ b/builtin-benchmarks/base64.jsonnet @@ -0,0 +1,5 @@ +{ + foo: [ + std.base64("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sed turpis tincidunt id aliquet risus. Eget mauris pharetra et ultrices neque ornare aenean euismod. Diam quis enim lobortis scelerisque fermentum. Varius duis at consectetur lorem donec massa sapien. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Lectus urna duis convallis convallis tellus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Feugiat in ante metus dictum at tempor commodo. Velit dignissim sodales ut eu sem integer. Dictum sit amet justo donec. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sed turpis tincidunt id aliquet risus. Eget mauris pharetra et ultrices neque ornare aenean euismod. Diam quis enim lobortis scelerisque fermentum. Varius duis at consectetur lorem donec massa sapien. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Lectus urna duis convallis convallis tellus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Feugiat in ante metus dictum at tempor commodo. Velit dignissim sodales ut eu sem integer. Dictum sit amet justo donec. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sed turpis tincidunt id aliquet risus. Eget mauris pharetra et ultrices neque ornare aenean euismod. Diam quis enim lobortis scelerisque fermentum. Varius duis at consectetur lorem donec massa sapien. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Lectus urna duis convallis convallis tellus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Feugiat in ante metus dictum at tempor commodo. Velit dignissim sodales ut eu sem integer. Dictum sit amet justo donec. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sed turpis tincidunt id aliquet risus. Eget mauris pharetra et ultrices neque ornare aenean euismod. Diam quis enim lobortis scelerisque fermentum. Varius duis at consectetur lorem donec massa sapien. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Lectus urna duis convallis convallis tellus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Feugiat in ante metus dictum at tempor commodo. Velit dignissim sodales ut eu sem integer. Dictum sit amet justo donec. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Sed turpis tincidunt id aliquet risus. Eget mauris pharetra et ultrices neque ornare aenean euismod. Diam quis enim lobortis scelerisque fermentum. Varius duis at consectetur lorem donec massa sapien. Diam sit amet nisl suscipit adipiscing bibendum est ultricies integer. Lectus urna duis convallis convallis tellus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Feugiat in ante metus dictum at tempor commodo. Velit dignissim sodales ut eu sem integer. Dictum sit amet justo donec. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus.") for i in std.range(0,100) + ], +} \ No newline at end of file diff --git a/builtin-benchmarks/base64_byte_array.jsonnet b/builtin-benchmarks/base64_byte_array.jsonnet new file mode 100644 index 0000000..d0dda66 --- /dev/null +++ b/builtin-benchmarks/base64_byte_array.jsonnet @@ -0,0 +1,5 @@ +{ + foo: [ + std.base64([76,111,114,101,109,32,105,112,115,117,109,32,100,111,108,111,114,32,115,105,116,32,97,109,101,116,44,32,99,111,110,115,101,99,116,101,116,117,114,32,97,100,105,112,105,115,99,105,110,103,32,101,108,105,116,44,32,115,101,100,32,100,111,32,101,105,117,115,109,111,100,32,116,101,109,112,111,114,32,105,110,99,105,100,105,100,117,110,116,32,117,116,32,108,97,98,111,114,101,32,101,116,32,100,111,108,111,114,101,32,109,97,103,110,97,32,97,108,105,113,117,97,46,32,83,101,100,32,116,117,114,112,105,115,32,116,105,110,99,105,100,117,110,116,32,105,100,32,97,108,105,113,117,101,116,32,114,105,115,117,115,46,32,69,103,101,116,32,109,97,117,114,105,115,32,112,104,97,114,101,116,114,97,32,101,116,32,117,108,116,114,105,99,101,115,32,110,101,113,117,101,32,111,114,110,97,114,101,32,97,101,110,101,97,110,32,101,117,105,115,109,111,100,46,32,68,105,97,109,32,113,117,105,115,32,101,110,105,109,32,108,111,98,111,114,116,105,115,32,115,99,101,108,101,114,105,115,113,117,101,32,102,101,114,109,101,110,116,117,109,46,32,86,97,114,105,117,115,32,100,117,105,115,32,97,116,32,99,111,110,115,101,99,116,101,116,117,114,32,108,111,114,101,109,32,100,111,110,101,99,32,109,97,115,115,97,32,115,97,112,105,101,110,46,32,68,105,97,109,32,115,105,116,32,97,109,101,116,32,110,105,115,108,32,115,117,115,99,105,112,105,116,32,97,100,105,112,105,115,99,105,110,103,32,98,105,98,101,110,100,117,109,32,101,115,116,32,117,108,116,114,105,99,105,101,115,32,105,110,116,101,103,101,114,46,32,76,101,99,116,117,115,32,117,114,110,97,32,100,117,105,115,32,99,111,110,118,97,108,108,105,115,32,99,111,110,118,97,108,108,105,115,32,116,101,108,108,117,115,46,32,78,105,98,104,32,105,112,115,117,109,32,99,111,110,115,101,113,117,97,116,32,110,105,115,108,32,118,101,108,32,112,114,101,116,105,117,109,32,108,101,99,116,117,115,32,113,117,97,109,32,105,100,32,108,101,111,46,32,70,101,117,103,105,97,116,32,105,110,32,97,110,116,101,32,109,101,116,117,115,32,100,105,99,116,117,109,32,97,116,32,116,101,109,112,111,114,32,99,111,109,109,111,100,111,46,32,86,101,108,105,116,32,100,105,103,110,105,115,115,105,109,32,115,111,100,97,108,101,115,32,117,116,32,101,117,32,115,101,109,32,105,110,116,101,103,101,114,46,32,68,105,99,116,117,109,32,115,105,116,32,97,109,101,116,32,106,117,115,116,111,32,100,111,110,101,99,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,76,111,114,101,109,32,105,112,115,117,109,32,100,111,108,111,114,32,115,105,116,32,97,109,101,116,44,32,99,111,110,115,101,99,116,101,116,117,114,32,97,100,105,112,105,115,99,105,110,103,32,101,108,105,116,44,32,115,101,100,32,100,111,32,101,105,117,115,109,111,100,32,116,101,109,112,111,114,32,105,110,99,105,100,105,100,117,110,116,32,117,116,32,108,97,98,111,114,101,32,101,116,32,100,111,108,111,114,101,32,109,97,103,110,97,32,97,108,105,113,117,97,46,32,83,101,100,32,116,117,114,112,105,115,32,116,105,110,99,105,100,117,110,116,32,105,100,32,97,108,105,113,117,101,116,32,114,105,115,117,115,46,32,69,103,101,116,32,109,97,117,114,105,115,32,112,104,97,114,101,116,114,97,32,101,116,32,117,108,116,114,105,99,101,115,32,110,101,113,117,101,32,111,114,110,97,114,101,32,97,101,110,101,97,110,32,101,117,105,115,109,111,100,46,32,68,105,97,109,32,113,117,105,115,32,101,110,105,109,32,108,111,98,111,114,116,105,115,32,115,99,101,108,101,114,105,115,113,117,101,32,102,101,114,109,101,110,116,117,109,46,32,86,97,114,105,117,115,32,100,117,105,115,32,97,116,32,99,111,110,115,101,99,116,101,116,117,114,32,108,111,114,101,109,32,100,111,110,101,99,32,109,97,115,115,97,32,115,97,112,105,101,110,46,32,68,105,97,109,32,115,105,116,32,97,109,101,116,32,110,105,115,108,32,115,117,115,99,105,112,105,116,32,97,100,105,112,105,115,99,105,110,103,32,98,105,98,101,110,100,117,109,32,101,115,116,32,117,108,116,114,105,99,105,101,115,32,105,110,116,101,103,101,114,46,32,76,101,99,116,117,115,32,117,114,110,97,32,100,117,105,115,32,99,111,110,118,97,108,108,105,115,32,99,111,110,118,97,108,108,105,115,32,116,101,108,108,117,115,46,32,78,105,98,104,32,105,112,115,117,109,32,99,111,110,115,101,113,117,97,116,32,110,105,115,108,32,118,101,108,32,112,114,101,116,105,117,109,32,108,101,99,116,117,115,32,113,117,97,109,32,105,100,32,108,101,111,46,32,70,101,117,103,105,97,116,32,105,110,32,97,110,116,101,32,109,101,116,117,115,32,100,105,99,116,117,109,32,97,116,32,116,101,109,112,111,114,32,99,111,109,109,111,100,111,46,32,86,101,108,105,116,32,100,105,103,110,105,115,115,105,109,32,115,111,100,97,108,101,115,32,117,116,32,101,117,32,115,101,109,32,105,110,116,101,103,101,114,46,32,68,105,99,116,117,109,32,115,105,116,32,97,109,101,116,32,106,117,115,116,111,32,100,111,110,101,99,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,76,111,114,101,109,32,105,112,115,117,109,32,100,111,108,111,114,32,115,105,116,32,97,109,101,116,44,32,99,111,110,115,101,99,116,101,116,117,114,32,97,100,105,112,105,115,99,105,110,103,32,101,108,105,116,44,32,115,101,100,32,100,111,32,101,105,117,115,109,111,100,32,116,101,109,112,111,114,32,105,110,99,105,100,105,100,117,110,116,32,117,116,32,108,97,98,111,114,101,32,101,116,32,100,111,108,111,114,101,32,109,97,103,110,97,32,97,108,105,113,117,97,46,32,83,101,100,32,116,117,114,112,105,115,32,116,105,110,99,105,100,117,110,116,32,105,100,32,97,108,105,113,117,101,116,32,114,105,115,117,115,46,32,69,103,101,116,32,109,97,117,114,105,115,32,112,104,97,114,101,116,114,97,32,101,116,32,117,108,116,114,105,99,101,115,32,110,101,113,117,101,32,111,114,110,97,114,101,32,97,101,110,101,97,110,32,101,117,105,115,109,111,100,46,32,68,105,97,109,32,113,117,105,115,32,101,110,105,109,32,108,111,98,111,114,116,105,115,32,115,99,101,108,101,114,105,115,113,117,101,32,102,101,114,109,101,110,116,117,109,46,32,86,97,114,105,117,115,32,100,117,105,115,32,97,116,32,99,111,110,115,101,99,116,101,116,117,114,32,108,111,114,101,109,32,100,111,110,101,99,32,109,97,115,115,97,32,115,97,112,105,101,110,46,32,68,105,97,109,32,115,105,116,32,97,109,101,116,32,110,105,115,108,32,115,117,115,99,105,112,105,116,32,97,100,105,112,105,115,99,105,110,103,32,98,105,98,101,110,100,117,109,32,101,115,116,32,117,108,116,114,105,99,105,101,115,32,105,110,116,101,103,101,114,46,32,76,101,99,116,117,115,32,117,114,110,97,32,100,117,105,115,32,99,111,110,118,97,108,108,105,115,32,99,111,110,118,97,108,108,105,115,32,116,101,108,108,117,115,46,32,78,105,98,104,32,105,112,115,117,109,32,99,111,110,115,101,113,117,97,116,32,110,105,115,108,32,118,101,108,32,112,114,101,116,105,117,109,32,108,101,99,116,117,115,32,113,117,97,109,32,105,100,32,108,101,111,46,32,70,101,117,103,105,97,116,32,105,110,32,97,110,116,101,32,109,101,116,117,115,32,100,105,99,116,117,109,32,97,116,32,116,101,109,112,111,114,32,99,111,109,109,111,100,111,46,32,86,101,108,105,116,32,100,105,103,110,105,115,115,105,109,32,115,111,100,97,108,101,115,32,117,116,32,101,117,32,115,101,109,32,105,110,116,101,103,101,114,46,32,68,105,99,116,117,109,32,115,105,116,32,97,109,101,116,32,106,117,115,116,111,32,100,111,110,101,99,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,76,111,114,101,109,32,105,112,115,117,109,32,100,111,108,111,114,32,115,105,116,32,97,109,101,116,44,32,99,111,110,115,101,99,116,101,116,117,114,32,97,100,105,112,105,115,99,105,110,103,32,101,108,105,116,44,32,115,101,100,32,100,111,32,101,105,117,115,109,111,100,32,116,101,109,112,111,114,32,105,110,99,105,100,105,100,117,110,116,32,117,116,32,108,97,98,111,114,101,32,101,116,32,100,111,108,111,114,101,32,109,97,103,110,97,32,97,108,105,113,117,97,46,32,83,101,100,32,116,117,114,112,105,115,32,116,105,110,99,105,100,117,110,116,32,105,100,32,97,108,105,113,117,101,116,32,114,105,115,117,115,46,32,69,103,101,116,32,109,97,117,114,105,115,32,112,104,97,114,101,116,114,97,32,101,116,32,117,108,116,114,105,99,101,115,32,110,101,113,117,101,32,111,114,110,97,114,101,32,97,101,110,101,97,110,32,101,117,105,115,109,111,100,46,32,68,105,97,109,32,113,117,105,115,32,101,110,105,109,32,108,111,98,111,114,116,105,115,32,115,99,101,108,101,114,105,115,113,117,101,32,102,101,114,109,101,110,116,117,109,46,32,86,97,114,105,117,115,32,100,117,105,115,32,97,116,32,99,111,110,115,101,99,116,101,116,117,114,32,108,111,114,101,109,32,100,111,110,101,99,32,109,97,115,115,97,32,115,97,112,105,101,110,46,32,68,105,97,109,32,115,105,116,32,97,109,101,116,32,110,105,115,108,32,115,117,115,99,105,112,105,116,32,97,100,105,112,105,115,99,105,110,103,32,98,105,98,101,110,100,117,109,32,101,115,116,32,117,108,116,114,105,99,105,101,115,32,105,110,116,101,103,101,114,46,32,76,101,99,116,117,115,32,117,114,110,97,32,100,117,105,115,32,99,111,110,118,97,108,108,105,115,32,99,111,110,118,97,108,108,105,115,32,116,101,108,108,117,115,46,32,78,105,98,104,32,105,112,115,117,109,32,99,111,110,115,101,113,117,97,116,32,110,105,115,108,32,118,101,108,32,112,114,101,116,105,117,109,32,108,101,99,116,117,115,32,113,117,97,109,32,105,100,32,108,101,111,46,32,70,101,117,103,105,97,116,32,105,110,32,97,110,116,101,32,109,101,116,117,115,32,100,105,99,116,117,109,32,97,116,32,116,101,109,112,111,114,32,99,111,109,109,111,100,111,46,32,86,101,108,105,116,32,100,105,103,110,105,115,115,105,109,32,115,111,100,97,108,101,115,32,117,116,32,101,117,32,115,101,109,32,105,110,116,101,103,101,114,46,32,68,105,99,116,117,109,32,115,105,116,32,97,109,101,116,32,106,117,115,116,111,32,100,111,110,101,99,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,76,111,114,101,109,32,105,112,115,117,109,32,100,111,108,111,114,32,115,105,116,32,97,109,101,116,44,32,99,111,110,115,101,99,116,101,116,117,114,32,97,100,105,112,105,115,99,105,110,103,32,101,108,105,116,44,32,115,101,100,32,100,111,32,101,105,117,115,109,111,100,32,116,101,109,112,111,114,32,105,110,99,105,100,105,100,117,110,116,32,117,116,32,108,97,98,111,114,101,32,101,116,32,100,111,108,111,114,101,32,109,97,103,110,97,32,97,108,105,113,117,97,46,32,83,101,100,32,116,117,114,112,105,115,32,116,105,110,99,105,100,117,110,116,32,105,100,32,97,108,105,113,117,101,116,32,114,105,115,117,115,46,32,69,103,101,116,32,109,97,117,114,105,115,32,112,104,97,114,101,116,114,97,32,101,116,32,117,108,116,114,105,99,101,115,32,110,101,113,117,101,32,111,114,110,97,114,101,32,97,101,110,101,97,110,32,101,117,105,115,109,111,100,46,32,68,105,97,109,32,113,117,105,115,32,101,110,105,109,32,108,111,98,111,114,116,105,115,32,115,99,101,108,101,114,105,115,113,117,101,32,102,101,114,109,101,110,116,117,109,46,32,86,97,114,105,117,115,32,100,117,105,115,32,97,116,32,99,111,110,115,101,99,116,101,116,117,114,32,108,111,114,101,109,32,100,111,110,101,99,32,109,97,115,115,97,32,115,97,112,105,101,110,46,32,68,105,97,109,32,115,105,116,32,97,109,101,116,32,110,105,115,108,32,115,117,115,99,105,112,105,116,32,97,100,105,112,105,115,99,105,110,103,32,98,105,98,101,110,100,117,109,32,101,115,116,32,117,108,116,114,105,99,105,101,115,32,105,110,116,101,103,101,114,46,32,76,101,99,116,117,115,32,117,114,110,97,32,100,117,105,115,32,99,111,110,118,97,108,108,105,115,32,99,111,110,118,97,108,108,105,115,32,116,101,108,108,117,115,46,32,78,105,98,104,32,105,112,115,117,109,32,99,111,110,115,101,113,117,97,116,32,110,105,115,108,32,118,101,108,32,112,114,101,116,105,117,109,32,108,101,99,116,117,115,32,113,117,97,109,32,105,100,32,108,101,111,46,32,70,101,117,103,105,97,116,32,105,110,32,97,110,116,101,32,109,101,116,117,115,32,100,105,99,116,117,109,32,97,116,32,116,101,109,112,111,114,32,99,111,109,109,111,100,111,46,32,86,101,108,105,116,32,100,105,103,110,105,115,115,105,109,32,115,111,100,97,108,101,115,32,117,116,32,101,117,32,115,101,109,32,105,110,116,101,103,101,114,46,32,68,105,99,116,117,109,32,115,105,116,32,97,109,101,116,32,106,117,115,116,111,32,100,111,110,101,99,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115,46,32,83,99,101,108,101,114,105,115,113,117,101,32,109,97,117,114,105,115,32,112,101,108,108,101,110,116,101,115,113,117,101,32,112,117,108,118,105,110,97,114,32,112,101,108,108,101,110,116,101,115,113,117,101,32,104,97,98,105,116,97,110,116,32,109,111,114,98,105,32,116,114,105,115,116,105,113,117,101,32,115,101,110,101,99,116,117,115]),for i in std.range(0,100) + ], +} \ No newline at end of file diff --git a/builtins.go b/builtins.go index f4137ed..0e750d0 100644 --- a/builtins.go +++ b/builtins.go @@ -19,6 +19,7 @@ package jsonnet import ( "bytes" "crypto/md5" + "encoding/base64" "encoding/hex" "encoding/json" "fmt" @@ -681,6 +682,69 @@ func builtinMd5(i *interpreter, trace traceElement, x value) (value, error) { return makeValueString(hex.EncodeToString(hash[:])), nil } +func builtinBase64(i *interpreter, trace traceElement, input value) (value, error) { + var byteArr []byte + + var sanityCheck = func(v int) (string, bool) { + if v < 0 || 255 < v { + msg := fmt.Sprintf("base64 encountered invalid codepoint value in the array (must be 0 <= X <= 255), got %d", v) + return msg, false + } + + return "", true + } + + switch input.(type) { + case valueString: + vStr, err := i.getString(input, trace) + if err != nil { + return nil, err + } + + runes := []rune(vStr.getGoString()) + for _, r := range runes { + n := int(r) + msg, ok := sanityCheck(n) + if !ok { + return nil, makeRuntimeError(msg, i.getCurrentStackTrace(trace)) + } + } + + byteArr = []byte(string(vStr.getGoString())) + case *valueArray: + vArr, err := i.getArray(input, trace) + if err != nil { + return nil, err + } + + for _, cThunk := range vArr.elements { + cTv, err := cThunk.getValue(i, trace) + if err != nil { + return nil, err + } + + vInt, err := i.getInt(cTv, trace) + if err != nil { + msg := fmt.Sprintf("base64 encountered a non-integer value in the array, got %s", cTv.getType().name) + return nil, makeRuntimeError(msg, i.getCurrentStackTrace(trace)) + } + + msg, ok := sanityCheck(vInt) + if !ok { + return nil, makeRuntimeError(msg, i.getCurrentStackTrace(trace)) + } + + byteArr = append(byteArr, byte(vInt)) + } + default: + msg := fmt.Sprintf("base64 can only base64 encode strings / arrays of single bytes, got %s", input.getType().name) + return nil, makeRuntimeError(msg, i.getCurrentStackTrace(trace)) + } + + sEnc := base64.StdEncoding.EncodeToString(byteArr) + return makeValueString(sEnc), nil +} + func builtinEncodeUTF8(i *interpreter, trace traceElement, x value) (value, error) { str, err := i.getString(x, trace) if err != nil { @@ -1318,6 +1382,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{ &ternaryBuiltin{name: "splitLimit", function: builtinSplitLimit, parameters: ast.Identifiers{"str", "c", "maxsplits"}}, &ternaryBuiltin{name: "strReplace", function: builtinStrReplace, parameters: ast.Identifiers{"str", "from", "to"}}, &unaryBuiltin{name: "parseJson", function: builtinParseJSON, parameters: ast.Identifiers{"str"}}, + &unaryBuiltin{name: "base64", function: builtinBase64, parameters: ast.Identifiers{"input"}}, &unaryBuiltin{name: "encodeUTF8", function: builtinEncodeUTF8, parameters: ast.Identifiers{"str"}}, &unaryBuiltin{name: "decodeUTF8", function: builtinDecodeUTF8, parameters: ast.Identifiers{"arr"}}, &generalBuiltin{name: "sort", function: builtinSort, required: ast.Identifiers{"arr"}, optional: ast.Identifiers{"keyF"}, defaultValues: []value{functionID}}, diff --git a/builtins_benchmark_test.go b/builtins_benchmark_test.go index db30ffc..d92e1d8 100644 --- a/builtins_benchmark_test.go +++ b/builtins_benchmark_test.go @@ -38,3 +38,11 @@ func Benchmark_Builtin_substr(b *testing.B) { func Benchmark_Builtin_reverse(b *testing.B) { RunBenchmark(b, "reverse") } + +func Benchmark_Builtin_base64(b *testing.B) { + RunBenchmark(b, "base64") +} + +func Benchmark_Builtin_base64_byte_array(b *testing.B) { + RunBenchmark(b, "base64_byte_array") +} diff --git a/testdata/builtinBase64.golden b/testdata/builtinBase64.golden new file mode 100644 index 0000000..0424f45 --- /dev/null +++ b/testdata/builtinBase64.golden @@ -0,0 +1 @@ +"aGVsbG8=" diff --git a/testdata/builtinBase64.jsonnet b/testdata/builtinBase64.jsonnet new file mode 100644 index 0000000..0159d22 --- /dev/null +++ b/testdata/builtinBase64.jsonnet @@ -0,0 +1 @@ +std.base64("hello") \ No newline at end of file diff --git a/testdata/builtinBase64_byte_array.golden b/testdata/builtinBase64_byte_array.golden new file mode 100644 index 0000000..0424f45 --- /dev/null +++ b/testdata/builtinBase64_byte_array.golden @@ -0,0 +1 @@ +"aGVsbG8=" diff --git a/testdata/builtinBase64_byte_array.jsonnet b/testdata/builtinBase64_byte_array.jsonnet new file mode 100644 index 0000000..9353516 --- /dev/null +++ b/testdata/builtinBase64_byte_array.jsonnet @@ -0,0 +1 @@ +std.base64([104, 101, 108, 108, 111]) \ No newline at end of file diff --git a/testdata/builtinBase64_invalid_byte_array.golden b/testdata/builtinBase64_invalid_byte_array.golden new file mode 100644 index 0000000..485cafd --- /dev/null +++ b/testdata/builtinBase64_invalid_byte_array.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: base64 encountered a non-integer value in the array, got string +------------------------------------------------- + testdata/builtinBase64_invalid_byte_array:1:1-23 builtin function + +std.base64([1, "foo"]) + +------------------------------------------------- + During evaluation + + diff --git a/testdata/builtinBase64_invalid_byte_array.jsonnet b/testdata/builtinBase64_invalid_byte_array.jsonnet new file mode 100644 index 0000000..db50491 --- /dev/null +++ b/testdata/builtinBase64_invalid_byte_array.jsonnet @@ -0,0 +1 @@ +std.base64([1, "foo"]) \ No newline at end of file diff --git a/testdata/builtinBase64_invalid_byte_array1.golden b/testdata/builtinBase64_invalid_byte_array1.golden new file mode 100644 index 0000000..bed4408 --- /dev/null +++ b/testdata/builtinBase64_invalid_byte_array1.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: base64 encountered invalid codepoint value in the array (must be 0 <= X <= 255), got -1 +------------------------------------------------- + testdata/builtinBase64_invalid_byte_array1:1:1-20 builtin function + +std.base64([1, -1]) + +------------------------------------------------- + During evaluation + + diff --git a/testdata/builtinBase64_invalid_byte_array1.jsonnet b/testdata/builtinBase64_invalid_byte_array1.jsonnet new file mode 100644 index 0000000..f0ca25f --- /dev/null +++ b/testdata/builtinBase64_invalid_byte_array1.jsonnet @@ -0,0 +1 @@ +std.base64([1, -1]) \ No newline at end of file diff --git a/testdata/builtinBase64_invalid_byte_array2.golden b/testdata/builtinBase64_invalid_byte_array2.golden new file mode 100644 index 0000000..9c12c9e --- /dev/null +++ b/testdata/builtinBase64_invalid_byte_array2.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: base64 encountered invalid codepoint value in the array (must be 0 <= X <= 255), got 256 +------------------------------------------------- + testdata/builtinBase64_invalid_byte_array2:1:1-21 builtin function + +std.base64([1, 256]) + +------------------------------------------------- + During evaluation + + diff --git a/testdata/builtinBase64_invalid_byte_array2.jsonnet b/testdata/builtinBase64_invalid_byte_array2.jsonnet new file mode 100644 index 0000000..511b0ec --- /dev/null +++ b/testdata/builtinBase64_invalid_byte_array2.jsonnet @@ -0,0 +1 @@ +std.base64([1, 256]) \ No newline at end of file diff --git a/testdata/builtinBase64_non_string_non_array.golden b/testdata/builtinBase64_non_string_non_array.golden new file mode 100644 index 0000000..543470d --- /dev/null +++ b/testdata/builtinBase64_non_string_non_array.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: base64 can only base64 encode strings / arrays of single bytes, got number +------------------------------------------------- + testdata/builtinBase64_non_string_non_array:1:1-14 builtin function + +std.base64(1) + +------------------------------------------------- + During evaluation + + diff --git a/testdata/builtinBase64_non_string_non_array.jsonnet b/testdata/builtinBase64_non_string_non_array.jsonnet new file mode 100644 index 0000000..dde96ab --- /dev/null +++ b/testdata/builtinBase64_non_string_non_array.jsonnet @@ -0,0 +1 @@ +std.base64(1) \ No newline at end of file diff --git a/testdata/builtinBase64_string_high_codepoint.golden b/testdata/builtinBase64_string_high_codepoint.golden new file mode 100644 index 0000000..536905b --- /dev/null +++ b/testdata/builtinBase64_string_high_codepoint.golden @@ -0,0 +1,10 @@ +RUNTIME ERROR: base64 encountered invalid codepoint value in the array (must be 0 <= X <= 255), got 256 +------------------------------------------------- + testdata/builtinBase64_string_high_codepoint:1:1-17 builtin function + +std.base64("Ā") + +------------------------------------------------- + During evaluation + + diff --git a/testdata/builtinBase64_string_high_codepoint.jsonnet b/testdata/builtinBase64_string_high_codepoint.jsonnet new file mode 100644 index 0000000..b9ce696 --- /dev/null +++ b/testdata/builtinBase64_string_high_codepoint.jsonnet @@ -0,0 +1 @@ +std.base64("Ā") \ No newline at end of file