From ad6c52846f13e4e86daa247c1369ed85558830e7 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 14 Nov 2022 11:58:10 +0900 Subject: [PATCH] Add error context callback when tokenizing authentication files The parsing of the authentication files for HBA and ident entries happens in two phases: - Tokenization of the files, creating a list of TokenizedAuthLines. - Validation of the HBA and ident entries, building a set of HbaLines or IdentLines. The second phase doing the validation provides already some error context about the configuration file and the line where a problem happens, but there is no such information in the first phase when tokenizing the files. This commit adds an ErrorContextCallback in tokenize_auth_file(), with a context made of the line number and the configuration file name involved in a problem. This is useful for files included in an HBA file for user and database lists, and it will become much more handy to track problems for files included via a potential @include[_dir,_if_exists]. The error context is registered so as the full chain of events is reported when using cascaded inclusions when for example tokenize_auth_file() recurses over itself on new files, displaying one context line for each file gone through when tokenizing things. Author: Michael Paquier Reviewed-by: Julien Rouhaud Discussion: https://postgr.es/m/Y2xUBJ+S+Z0zbxRW@paquier.xyz --- src/backend/libpq/hba.c | 31 +++++++++++++++++++++++++++++++ src/tools/pgindent/typedefs.list | 1 + 2 files changed, 32 insertions(+) diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index b3bd08f03d..abdebeb3f8 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -66,6 +66,11 @@ typedef struct check_network_data bool result; /* set to true if match */ } check_network_data; +typedef struct +{ + const char *filename; + int linenum; +} tokenize_error_callback_arg; #define token_has_regexp(t) (t->regex != NULL) #define token_is_keyword(t, k) (!t->quoted && strcmp(t->string, k) == 0) @@ -125,6 +130,7 @@ 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[]); +static void tokenize_error_callback(void *arg); /* @@ -570,6 +576,18 @@ open_auth_file(const char *filename, int elevel, int depth, return file; } +/* + * error context callback for tokenize_auth_file() + */ +static void +tokenize_error_callback(void *arg) +{ + tokenize_error_callback_arg *callback_arg = (tokenize_error_callback_arg *) arg; + + errcontext("line %d of configuration file \"%s\"", + callback_arg->linenum, callback_arg->filename); +} + /* * tokenize_auth_file * Tokenize the given file. @@ -598,6 +616,16 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines, StringInfoData buf; MemoryContext linecxt; MemoryContext oldcxt; + ErrorContextCallback tokenerrcontext; + tokenize_error_callback_arg callback_arg; + + callback_arg.filename = filename; + callback_arg.linenum = line_number; + + tokenerrcontext.callback = tokenize_error_callback; + tokenerrcontext.arg = (void *) &callback_arg; + tokenerrcontext.previous = error_context_stack; + error_context_stack = &tokenerrcontext; linecxt = AllocSetContextCreate(CurrentMemoryContext, "tokenize_auth_file", @@ -686,10 +714,13 @@ tokenize_auth_file(const char *filename, FILE *file, List **tok_lines, } line_number += continuations + 1; + callback_arg.linenum = line_number; } MemoryContextSwitchTo(oldcxt); + error_context_stack = tokenerrcontext.previous; + return linecxt; } diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 245aea1dd1..f8302f1ed1 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3723,6 +3723,7 @@ timeout_params timerCA tlist_vinfo toast_compress_header +tokenize_error_callback_arg transferMode transfer_thread_arg trgm -- 2.39.5