v1-0002-Make-implementation-of-SASLprep-compliant-for-ASC.patch

text/plain

Filename: v1-0002-Make-implementation-of-SASLprep-compliant-for-ASC.patch
Type: text/plain
Part: 1
Message: Non-compliant SASLprep implementation for ASCII characters

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v1-0002
Subject: Make implementation of SASLprep compliant for ASCII characters
File+
src/common/saslprep.c 0 12
src/test/modules/test_saslprep/expected/test_saslprep.out 32 32
src/test/modules/test_saslprep/t/001_saslprep_ranges.pl 1 3
From 639d385eaee847ed09e575b3664a80783de795e8 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Fri, 27 Feb 2026 11:42:50 +0900
Subject: [PATCH v1 2/2] Make implementation of SASLprep compliant for ASCII
 characters

---
 src/common/saslprep.c                         | 12 ----
 .../test_saslprep/expected/test_saslprep.out  | 64 +++++++++----------
 .../test_saslprep/t/001_saslprep_ranges.pl    |  4 +-
 3 files changed, 33 insertions(+), 47 deletions(-)

diff --git a/src/common/saslprep.c b/src/common/saslprep.c
index 2ad2cefc14fb..38d50dd823c4 100644
--- a/src/common/saslprep.c
+++ b/src/common/saslprep.c
@@ -1061,18 +1061,6 @@ pg_saslprep(const char *input, char **output)
 	/* Ensure we return *output as NULL on failure */
 	*output = NULL;
 
-	/*
-	 * Quick check if the input is pure ASCII.  An ASCII string requires no
-	 * further processing.
-	 */
-	if (pg_is_ascii(input))
-	{
-		*output = STRDUP(input);
-		if (!(*output))
-			goto oom;
-		return SASLPREP_SUCCESS;
-	}
-
 	/*
 	 * Convert the input from UTF-8 to an array of Unicode codepoints.
 	 *
diff --git a/src/test/modules/test_saslprep/expected/test_saslprep.out b/src/test/modules/test_saslprep/expected/test_saslprep.out
index 5a0ded7b4214..deeab303fa52 100644
--- a/src/test/modules/test_saslprep/expected/test_saslprep.out
+++ b/src/test/modules/test_saslprep/expected/test_saslprep.out
@@ -12,38 +12,38 @@ SELECT chr(a) AS dat, chr(a)::bytea AS byt, test_saslprep(chr(a)::bytea)
   FROM generate_series(1,91) as a;
    dat    | byt  |   test_saslprep   
 ----------+------+-------------------
- \x01     | \x01 | ("\\x01",SUCCESS)
- \x02     | \x02 | ("\\x02",SUCCESS)
- \x03     | \x03 | ("\\x03",SUCCESS)
- \x04     | \x04 | ("\\x04",SUCCESS)
- \x05     | \x05 | ("\\x05",SUCCESS)
- \x06     | \x06 | ("\\x06",SUCCESS)
- \x07     | \x07 | ("\\x07",SUCCESS)
- \x08     | \x08 | ("\\x08",SUCCESS)
-          | \x09 | ("\\x09",SUCCESS)
-         +| \x0a | ("\\x0a",SUCCESS)
+ \x01     | \x01 | (,PROHIBITED)
+ \x02     | \x02 | (,PROHIBITED)
+ \x03     | \x03 | (,PROHIBITED)
+ \x04     | \x04 | (,PROHIBITED)
+ \x05     | \x05 | (,PROHIBITED)
+ \x06     | \x06 | (,PROHIBITED)
+ \x07     | \x07 | (,PROHIBITED)
+ \x08     | \x08 | (,PROHIBITED)
+          | \x09 | (,PROHIBITED)
+         +| \x0a | (,PROHIBITED)
           |      | 
- \x0B     | \x0b | ("\\x0b",SUCCESS)
- \x0C     | \x0c | ("\\x0c",SUCCESS)
- \r       | \x0d | ("\\x0d",SUCCESS)
- \x0E     | \x0e | ("\\x0e",SUCCESS)
- \x0F     | \x0f | ("\\x0f",SUCCESS)
- \x10     | \x10 | ("\\x10",SUCCESS)
- \x11     | \x11 | ("\\x11",SUCCESS)
- \x12     | \x12 | ("\\x12",SUCCESS)
- \x13     | \x13 | ("\\x13",SUCCESS)
- \x14     | \x14 | ("\\x14",SUCCESS)
- \x15     | \x15 | ("\\x15",SUCCESS)
- \x16     | \x16 | ("\\x16",SUCCESS)
- \x17     | \x17 | ("\\x17",SUCCESS)
- \x18     | \x18 | ("\\x18",SUCCESS)
- \x19     | \x19 | ("\\x19",SUCCESS)
- \x1A     | \x1a | ("\\x1a",SUCCESS)
- \x1B     | \x1b | ("\\x1b",SUCCESS)
- \x1C     | \x1c | ("\\x1c",SUCCESS)
- \x1D     | \x1d | ("\\x1d",SUCCESS)
- \x1E     | \x1e | ("\\x1e",SUCCESS)
- \x1F     | \x1f | ("\\x1f",SUCCESS)
+ \x0B     | \x0b | (,PROHIBITED)
+ \x0C     | \x0c | (,PROHIBITED)
+ \r       | \x0d | (,PROHIBITED)
+ \x0E     | \x0e | (,PROHIBITED)
+ \x0F     | \x0f | (,PROHIBITED)
+ \x10     | \x10 | (,PROHIBITED)
+ \x11     | \x11 | (,PROHIBITED)
+ \x12     | \x12 | (,PROHIBITED)
+ \x13     | \x13 | (,PROHIBITED)
+ \x14     | \x14 | (,PROHIBITED)
+ \x15     | \x15 | (,PROHIBITED)
+ \x16     | \x16 | (,PROHIBITED)
+ \x17     | \x17 | (,PROHIBITED)
+ \x18     | \x18 | (,PROHIBITED)
+ \x19     | \x19 | (,PROHIBITED)
+ \x1A     | \x1a | (,PROHIBITED)
+ \x1B     | \x1b | (,PROHIBITED)
+ \x1C     | \x1c | (,PROHIBITED)
+ \x1D     | \x1d | (,PROHIBITED)
+ \x1E     | \x1e | (,PROHIBITED)
+ \x1F     | \x1f | (,PROHIBITED)
           | \x20 | ("\\x20",SUCCESS)
  !        | \x21 | ("\\x21",SUCCESS)
  "        | \x22 | ("\\x22",SUCCESS)
@@ -144,7 +144,7 @@ SELECT chr(a) AS dat, chr(a)::bytea AS byt, test_saslprep(chr(a)::bytea)
  |    | \x7c | ("\\x7c",SUCCESS)
  }    | \x7d | ("\\x7d",SUCCESS)
  ~    | \x7e | ("\\x7e",SUCCESS)
- \x7F | \x7f | ("\\x7f",SUCCESS)
+ \x7F | \x7f | (,PROHIBITED)
 (35 rows)
 
 DROP EXTENSION test_saslprep;
diff --git a/src/test/modules/test_saslprep/t/001_saslprep_ranges.pl b/src/test/modules/test_saslprep/t/001_saslprep_ranges.pl
index b2b40e9108b6..cf455571dd2b 100644
--- a/src/test/modules/test_saslprep/t/001_saslprep_ranges.pl
+++ b/src/test/modules/test_saslprep/t/001_saslprep_ranges.pl
@@ -25,14 +25,12 @@ $node->safe_psql('postgres', 'CREATE EXTENSION test_saslprep;');
 # Among all the valid UTF-8 codepoint ranges, our implementation of
 # SASLprep should never return an empty password if the operation is
 # considered a success.
-# The only exception is the nul character, prohibited in input of
-# CREATE/ALTER ROLE.
 my $result = $node->safe_psql(
 	'postgres', qq[SELECT * FROM test_saslprep_ranges()
   WHERE status = 'SUCCESS' AND res IN (NULL, '')
 ]);
 
-is($result, 'U+0000|SUCCESS|\x00|\x', "Only nul authorized for all valid UTF8 codepoints");
+is($result, '', "No empty or NULL values for all valid UTF8 codepoints");
 
 $node->stop;
 done_testing();
-- 
2.53.0