From a903971351023bf08b3d6165220d0c8ab8ddada3 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Fri, 21 Oct 2022 09:55:56 +0900 Subject: [PATCH] Refactor more logic for compilation of regular expressions in hba.c It happens that the parts of hba.conf that are planned to be extended to support regular expressions would finish by using the same error message as the one used currently for pg_ident.conf when a regular expression cannot be compiled, as long as the routine centralizing the logic, regcomp_auth_token(), knows from which file the regexp comes from and its line location in the so-said file. This change makes the follow-up patches slightly simpler, and the logic remains the same. I suspect that this makes the proposal to add support for file inclusions in pg_ident.conf and pg_hba.conf slightly simpler, as well. Extracted from a larger patch by the same author. This is similar to the refactoring done in fc579e1. Author: Bertrand Drouvot Discussion: https://postgr.es/m/fff0d7c1-8ad4-76a1-9db3-0ab6ec338bf7@amazon.com --- src/backend/libpq/hba.c | 44 +++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 947a1edcef..f3539a7929 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -119,7 +119,8 @@ static List *tokenize_inc_file(List *tokens, const char *outer_filename, const char *inc_filename, int elevel, char **err_msg); static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg); -static int regcomp_auth_token(AuthToken *token); +static int regcomp_auth_token(AuthToken *token, char *filename, int line_num, + char **err_msg, int elevel); static int regexec_auth_token(const char *match, AuthToken *token, size_t nmatch, regmatch_t pmatch[]); @@ -305,10 +306,12 @@ copy_auth_token(AuthToken *in) /* * Compile the regular expression and store it in the AuthToken given in - * input. Returns the result of pg_regcomp(). + * input. Returns the result of pg_regcomp(). On error, the details are + * stored in "err_msg". */ static int -regcomp_auth_token(AuthToken *token) +regcomp_auth_token(AuthToken *token, char *filename, int line_num, + char **err_msg, int elevel) { pg_wchar *wstr; int wlen; @@ -326,6 +329,22 @@ regcomp_auth_token(AuthToken *token) rc = pg_regcomp(token->regex, wstr, wlen, REG_ADVANCED, C_COLLATION_OID); + if (rc) + { + char errstr[100]; + + pg_regerror(rc, token->regex, errstr, sizeof(errstr)); + ereport(elevel, + (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), + errmsg("invalid regular expression \"%s\": %s", + token->string + 1, errstr), + errcontext("line %d of configuration file \"%s\"", + line_num, filename))); + + *err_msg = psprintf("invalid regular expression \"%s\": %s", + token->string + 1, errstr); + } + pfree(wstr); return rc; } @@ -2374,7 +2393,6 @@ parse_ident_line(TokenizedAuthLine *tok_line, int elevel) List *tokens; AuthToken *token; IdentLine *parsedline; - int rc; Assert(tok_line->fields != NIL); field = list_head(tok_line->fields); @@ -2410,22 +2428,10 @@ parse_ident_line(TokenizedAuthLine *tok_line, int elevel) * Now that the field validation is done, compile a regex from the user * token, if necessary. */ - rc = regcomp_auth_token(parsedline->token); - if (rc) + if (regcomp_auth_token(parsedline->token, IdentFileName, line_num, + err_msg, elevel)) { - char errstr[100]; - - pg_regerror(rc, parsedline->token->regex, errstr, sizeof(errstr)); - ereport(elevel, - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), - errmsg("invalid regular expression \"%s\": %s", - parsedline->token->string + 1, errstr), - errcontext("line %d of configuration file \"%s\"", - line_num, IdentFileName))); - - *err_msg = psprintf("invalid regular expression \"%s\": %s", - parsedline->token->string + 1, errstr); - + /* err_msg includes the error to report */ return NULL; }