From 9e8d835669705f7e13da3b401a272995c4225531 Mon Sep 17 00:00:00 2001
From: Florents Tselai <florents.tselai@gmail.com>
Date: Wed, 4 Jun 2025 10:56:23 +0300
Subject: [PATCH v4 3/3] Add more test cases for shorter inputs and errors.

---
 src/test/regress/expected/strings.out | 147 +++++++++++++++++++++-----
 src/test/regress/sql/strings.sql      |  64 ++++++++---
 2 files changed, 170 insertions(+), 41 deletions(-)

diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out
index 80e2ff8426c..28ab4b52222 100644
--- a/src/test/regress/expected/strings.out
+++ b/src/test/regress/expected/strings.out
@@ -2342,60 +2342,153 @@ SELECT decode(encode('\x1234567890abcdef00', 'escape'), 'escape');
 (1 row)
 
 --
--- encode/decode Base64URL
+-- Base64URL encoding/decoding
 --
 SET bytea_output TO hex;
--- Flaghsip Test case against base64.
--- Notice the = padding removed at the end and special chars.
-SELECT encode('\x69b73eff', 'base64');  -- Expected: abc+/w==
-  encode  
-----------
- abc+/w==
-(1 row)
-
-SELECT encode('\x69b73eff', 'base64url');  -- Expected: abc-_w
+-- Simple encoding/decoding
+SELECT encode('\x69b73eff', 'base64url');  -- abc-_w
  encode 
 --------
  abc-_w
 (1 row)
 
-SELECT decode(encode('\x69b73eff', 'base64url'), 'base64url');
+SELECT decode('abc-_w', 'base64url');      -- \x69b73eff
    decode   
 ------------
  \x69b73eff
 (1 row)
 
--- Test basic encoding/decoding
-SELECT encode('\x1234567890abcdef00', 'base64url');  -- Expected: EjRWeJCrze8A
-    encode    
---------------
- EjRWeJCrze8A
-(1 row)
-
-SELECT decode(encode('\x1234567890abcdef00', 'base64url'), 'base64url');  -- Expected: \x1234567890abcdef00
+-- Round-trip: decode(encode(x)) = x
+SELECT decode(encode('\x1234567890abcdef00', 'base64url'), 'base64url');  -- \x1234567890abcdef00
         decode        
 ----------------------
  \x1234567890abcdef00
 (1 row)
 
--- Test with empty input
-SELECT encode('', 'base64url');
+-- Empty input
+SELECT encode('', 'base64url');  -- ''
  encode 
 --------
  
 (1 row)
 
-SELECT decode('', 'base64url');
+SELECT decode('', 'base64url');  -- ''
  decode 
 --------
  \x
 (1 row)
 
--- Test round-trip conversion
-SELECT encode(decode('SGVsbG8gV29ybGQh', 'base64url'), 'base64url');  -- Expected: SGVsbG8gV29ybGQh (decodes to "Hello World!")
-      encode      
-------------------
- SGVsbG8gV29ybGQh
+-- 1 byte input
+SELECT encode('\x01', 'base64url');  -- AQ==
+ encode 
+--------
+ AQ
+(1 row)
+
+SELECT decode('AQ', 'base64url');    -- \x01
+ decode 
+--------
+ \x01
+(1 row)
+
+-- 2 byte input
+SELECT encode('\x0102'::bytea, 'base64url');  -- AQI
+ encode 
+--------
+ AQI
+(1 row)
+
+SELECT decode('AQI', 'base64url');            -- \x0102
+ decode 
+--------
+ \x0102
+(1 row)
+
+-- 3 byte input (no padding needed)
+SELECT encode('\x010203'::bytea, 'base64url');  -- AQID
+ encode 
+--------
+ AQID
+(1 row)
+
+SELECT decode('AQID', 'base64url');             -- \x010203
+  decode  
+----------
+ \x010203
+(1 row)
+
+-- 4 byte input (results in 6 base64 chars)
+SELECT encode('\xdeadbeef'::bytea, 'base64url');  -- 3q2-7w
+ encode 
+--------
+ 3q2-7w
+(1 row)
+
+SELECT decode('3q2-7w', 'base64url');             -- \xdeadbeef
+   decode   
+------------
+ \xdeadbeef
+(1 row)
+
+-- Round-trip test for all lengths from 0–4
+SELECT encode(decode(encode(E'\\x', 'base64url'), 'base64url'), 'base64url');
+ encode 
+--------
+ 
+(1 row)
+
+SELECT encode(decode(encode(E'\\x00', 'base64url'), 'base64url'), 'base64url');
+ encode 
+--------
+ AA
+(1 row)
+
+SELECT encode(decode(encode(E'\\x0001', 'base64url'), 'base64url'), 'base64url');
+ encode 
+--------
+ AAE
+(1 row)
+
+SELECT encode(decode(encode(E'\\x000102', 'base64url'), 'base64url'), 'base64url');
+ encode 
+--------
+ AAEC
+(1 row)
+
+SELECT encode(decode(encode(E'\\x00010203', 'base64url'), 'base64url'), 'base64url');
+ encode 
+--------
+ AAECAw
+(1 row)
+
+-- Invalid inputs (should ERROR)
+-- invalid character '@'
+SELECT decode('QQ@=', 'base64url');
+ERROR:  invalid symbol "@" found while decoding base64 sequence
+-- missing characters (incomplete group)
+SELECT decode('QQ', 'base64url');  -- ok (1 byte)
+ decode 
+--------
+ \x41
+(1 row)
+
+SELECT decode('QQI', 'base64url'); -- ok (2 bytes)
+ decode 
+--------
+ \x4102
+(1 row)
+
+SELECT decode('QQIDQ', 'base64url'); -- ERROR: invalid base64 end sequence
+ERROR:  invalid base64 end sequence
+HINT:  Input data is missing padding, is truncated, or is otherwise corrupted.
+-- unexpected '=' at start
+SELECT decode('=QQQ', 'base64url');
+ERROR:  unexpected "=" while decoding base64 sequence
+-- valid base64 padding in base64url (optional, but accepted)
+SELECT decode('abc-_w==', 'base64url');  -- should decode to \x69b73eff
+   decode   
+------------
+ \x69b73eff
 (1 row)
 
 --
diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql
index d14c1cac28f..51b4de5bc90 100644
--- a/src/test/regress/sql/strings.sql
+++ b/src/test/regress/sql/strings.sql
@@ -744,22 +744,58 @@ SELECT encode('\x1234567890abcdef00', 'escape');
 SELECT decode(encode('\x1234567890abcdef00', 'escape'), 'escape');
 
 --
--- encode/decode Base64URL
+-- Base64URL encoding/decoding
 --
 SET bytea_output TO hex;
--- Flaghsip Test case against base64.
--- Notice the = padding removed at the end and special chars.
-SELECT encode('\x69b73eff', 'base64');  -- Expected: abc+/w==
-SELECT encode('\x69b73eff', 'base64url');  -- Expected: abc-_w
-SELECT decode(encode('\x69b73eff', 'base64url'), 'base64url');
--- Test basic encoding/decoding
-SELECT encode('\x1234567890abcdef00', 'base64url');  -- Expected: EjRWeJCrze8A
-SELECT decode(encode('\x1234567890abcdef00', 'base64url'), 'base64url');  -- Expected: \x1234567890abcdef00
--- Test with empty input
-SELECT encode('', 'base64url');
-SELECT decode('', 'base64url');
--- Test round-trip conversion
-SELECT encode(decode('SGVsbG8gV29ybGQh', 'base64url'), 'base64url');  -- Expected: SGVsbG8gV29ybGQh (decodes to "Hello World!")
+
+-- Simple encoding/decoding
+SELECT encode('\x69b73eff', 'base64url');  -- abc-_w
+SELECT decode('abc-_w', 'base64url');      -- \x69b73eff
+
+-- Round-trip: decode(encode(x)) = x
+SELECT decode(encode('\x1234567890abcdef00', 'base64url'), 'base64url');  -- \x1234567890abcdef00
+
+-- Empty input
+SELECT encode('', 'base64url');  -- ''
+SELECT decode('', 'base64url');  -- ''
+
+-- 1 byte input
+SELECT encode('\x01', 'base64url');  -- AQ==
+SELECT decode('AQ', 'base64url');    -- \x01
+
+-- 2 byte input
+SELECT encode('\x0102'::bytea, 'base64url');  -- AQI
+SELECT decode('AQI', 'base64url');            -- \x0102
+
+-- 3 byte input (no padding needed)
+SELECT encode('\x010203'::bytea, 'base64url');  -- AQID
+SELECT decode('AQID', 'base64url');             -- \x010203
+
+-- 4 byte input (results in 6 base64 chars)
+SELECT encode('\xdeadbeef'::bytea, 'base64url');  -- 3q2-7w
+SELECT decode('3q2-7w', 'base64url');             -- \xdeadbeef
+
+-- Round-trip test for all lengths from 0–4
+SELECT encode(decode(encode(E'\\x', 'base64url'), 'base64url'), 'base64url');
+SELECT encode(decode(encode(E'\\x00', 'base64url'), 'base64url'), 'base64url');
+SELECT encode(decode(encode(E'\\x0001', 'base64url'), 'base64url'), 'base64url');
+SELECT encode(decode(encode(E'\\x000102', 'base64url'), 'base64url'), 'base64url');
+SELECT encode(decode(encode(E'\\x00010203', 'base64url'), 'base64url'), 'base64url');
+
+-- Invalid inputs (should ERROR)
+-- invalid character '@'
+SELECT decode('QQ@=', 'base64url');
+
+-- missing characters (incomplete group)
+SELECT decode('QQ', 'base64url');  -- ok (1 byte)
+SELECT decode('QQI', 'base64url'); -- ok (2 bytes)
+SELECT decode('QQIDQ', 'base64url'); -- ERROR: invalid base64 end sequence
+
+-- unexpected '=' at start
+SELECT decode('=QQQ', 'base64url');
+
+-- valid base64 padding in base64url (optional, but accepted)
+SELECT decode('abc-_w==', 'base64url');  -- should decode to \x69b73eff
 
 --
 -- get_bit/set_bit etc
-- 
2.49.0

