From: Daniel Gustafsson Date: Fri, 17 Jul 2026 13:40:16 +0000 (+0200) Subject: Fix truncation rules for base64 encoding X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5f57f58179bf48805558ac0494851e93fe0eca76;p=thirdparty%2Fpostgresql.git Fix truncation rules for base64 encoding Commit e1d917182 added support for base64url encoding, a base64 variant intended to be safe for usage in URLs and filenames. The padding rules for base64url and base64 differ in that base64url require no extra '=' padding, but the commit unintentionally relaxed this requirement for base64 as well. Fix by making sure that the truncation logic check for the encoding and add a test to make sure. Backpatch down to v19 where support for base64url was introduced. Author: Daniel Gustafsson Reviewed-by: David E. Wheeler Discussion: https://postgr.es/m/3258FC72-F5E1-40B9-B5D7-64478CAF7728@yesql.se Backpatch-through: 19 --- diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index 9ea3ddb49ec..b9d4f2811d7 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -583,12 +583,12 @@ pg_base64_decode_internal(const char *src, size_t len, char *dst, bool url) } } - if (pos == 2) + if (url && pos == 2) { buf <<= 12; *p++ = (buf >> 16) & 0xFF; } - else if (pos == 3) + else if (url && pos == 3) { buf <<= 6; *p++ = (buf >> 16) & 0xFF; diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index a49b75fa1f9..313c5039465 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -2810,6 +2810,10 @@ SELECT decode('AQ', 'base64url'); -- \x01 \x01 (1 row) +-- Make sure the same 1 byte input isn't accepted as base64 +SELECT decode('AQ', 'base64'); -- \x01 +ERROR: invalid base64 end sequence +HINT: Input data is missing padding, is truncated, or is otherwise corrupted. -- 2 byte input SELECT encode('\x0102'::bytea, 'base64url'); -- AQI encode diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 5ae0e7da31a..38946e8954d 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -909,6 +909,9 @@ SELECT decode('', 'base64url'); -- '' SELECT encode('\x01', 'base64url'); -- AQ SELECT decode('AQ', 'base64url'); -- \x01 +-- Make sure the same 1 byte input isn't accepted as base64 +SELECT decode('AQ', 'base64'); -- \x01 + -- 2 byte input SELECT encode('\x0102'::bytea, 'base64url'); -- AQI SELECT decode('AQI', 'base64url'); -- \x0102