From b933b04d68cdac098c7eeb32b88707f3be385fe6 Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Thu, 20 Apr 2023 13:17:09 -0700
Subject: [PATCH] Avoid character classification in regex escape parsing.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For regex escape sequences, just test directly for the relevant ASCII
characters rather than using locale-sensitive character
classification.

This fixes an assertion failure when a locale considers a non-ASCII
character, such as "൧", to be a digit.

Reported-by: Richard Guo
Discussion: https://postgr.es/m/CAMbWs49Q6UoKGeT8pBkMtJGJd+16CBFZaaWUk9Du+2ERE5g_YA@mail.gmail.com
---
 src/backend/regex/regc_lex.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c
index 4780d79f09..38c09b1123 100644
--- a/src/backend/regex/regc_lex.c
+++ b/src/backend/regex/regc_lex.c
@@ -613,7 +613,11 @@ lexescape(struct vars *v)
 
 	assert(!ATEOS());
 	c = *v->now++;
-	if (!iscalnum(c))
+
+	/* if it's not alphanumeric ASCII, treat it as a plain character */
+	if (!('a' <= c && c <= 'z') &&
+		!('A' <= c && c <= 'Z') &&
+		!('0' <= c && c <= '9'))
 		RETV(PLAIN, c);
 
 	NOTE(REG_UNONPOSIX);
@@ -755,8 +759,11 @@ lexescape(struct vars *v)
 			RETV(PLAIN, c);
 			break;
 		default:
-			assert(iscalpha(c));
-			FAILW(REG_EESCAPE); /* unknown alphabetic escape */
+			/*
+			 * Throw an error for unrecognized ASCII alpha escape sequences,
+			 * which reserves them for future use if needed.
+			 */
+			FAILW(REG_EESCAPE);
 			break;
 	}
 	assert(NOTREACHED);
-- 
2.34.1

