jqlang / jq

Command-line JSON processor
https://jqlang.github.io/jq/
Other
30.45k stars 1.58k forks source link

@base64d does not handle web-safe encoded base64 #2262

Open osresearch opened 3 years ago

osresearch commented 3 years ago

Describe the bug Many programs output "web safe" or "filename safe" base64 (defined in RFC 4648 and called base64url). In this format the / and + characters are replaced with _ and -, and the = padding is often URI escaped with %3D. The @base64d string formatter does not handle this variant.

To Reproduce

$ echo '_-8%3D' | jq -R -r '@base64d'
jq: error (at <stdin>:1): string ("_-%3D") is not valid base64 data

Expected behavior

$ echo '_-8%3D' | jq -R -r '@base64d' | xxd -g1
00000000: ff ef

Environment (please complete the following information):

Additional context Having a way to output the raw binary would be helpful, too. The @base64d does not output the two bytes 0xFF 0xFE, but instead does a UTF-8 expansion.

apstndb commented 3 years ago

I define functions to work around.

def base64url: @base64 | gsub("\\+"; "-") | gsub("/"; "_") | gsub("="; "");
def base64urld: gsub("-"; "+") | gsub("_"; "/") | gsub("%3D"; "=") | @base64d;

Having a way to output the raw binary would be helpful, too. The @base64d does not output the two bytes 0xFF 0xFE, but instead does a UTF-8 expansion.

Binary supports seems working in this PR. https://github.com/stedolan/jq/pull/2314

jfromaniello commented 2 years ago

@apstndb thanks, this helped me to create a jwt-decode function:

~ » cat ~/.jq
def base64url: @base64 | gsub("\\+"; "-") | gsub("/"; "_") | gsub("="; "");
def base64urld: gsub("-"; "+") | gsub("_"; "/") | gsub("%3D"; "=") | @base64d;

~ » function jwt-decode () {
  jq -R 'split(".") | .[1] | base64urld | fromjson'
}