Skip to content

Commit 350cb92

Browse files
committed
Restructure hba.c to replace 3 parallel lists with single list of structs.
tokenize_file() now returns a single list of TokenizedLine structs, carrying the same information as before. We were otherwise going to grow a fourth list to deal with error messages, and that was getting a bit silly. Haribabu Kommi, revised a bit by me Discussion: https://postgr.es/m/CAJrrPGfbgbKsjYp=bgZXhMcgxoaGSoBb9fyjrDoOW_YymXv1Kw@mail.gmail.com
1 parent fde5c03 commit 350cb92

File tree

1 file changed

+70
-64
lines changed

1 file changed

+70
-64
lines changed

src/backend/libpq/hba.c

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ typedef struct check_network_data
6666
#define token_matches(t, k) (strcmp(t->string, k) == 0)
6767

6868
/*
69-
* A single string token lexed from the HBA config file, together with whether
69+
* A single string token lexed from a config file, together with whether
7070
* the token had been quoted.
7171
*/
7272
typedef struct HbaToken
@@ -75,6 +75,19 @@ typedef struct HbaToken
7575
bool quoted;
7676
} HbaToken;
7777

78+
/*
79+
* TokenizedLine represents one line lexed from a config file.
80+
* Each item in the "fields" list is a sub-list of HbaTokens.
81+
* We don't emit a TokenizedLine for empty or all-comment lines,
82+
* so "fields" is never NIL (nor are any of its sub-lists).
83+
*/
84+
typedef struct TokenizedLine
85+
{
86+
List *fields; /* List of lists of HbaTokens */
87+
int line_num; /* Line number */
88+
char *raw_line; /* Raw line text */
89+
} TokenizedLine;
90+
7891
/*
7992
* pre-parsed content of HBA config file: list of HbaLine structs.
8093
* parsed_hba_context is the memory context where it lives.
@@ -95,7 +108,7 @@ static MemoryContext parsed_ident_context = NULL;
95108

96109

97110
static MemoryContext tokenize_file(const char *filename, FILE *file,
98-
List **lines, List **line_nums, List **raw_lines);
111+
List **tok_lines);
99112
static List *tokenize_inc_file(List *tokens, const char *outer_filename,
100113
const char *inc_filename);
101114
static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
@@ -305,7 +318,6 @@ tokenize_inc_file(List *tokens,
305318
char *inc_fullname;
306319
FILE *inc_file;
307320
List *inc_lines;
308-
List *inc_line_nums;
309321
ListCell *inc_line;
310322
MemoryContext linecxt;
311323

@@ -337,17 +349,18 @@ tokenize_inc_file(List *tokens,
337349
}
338350

339351
/* There is possible recursion here if the file contains @ */
340-
linecxt = tokenize_file(inc_fullname, inc_file, &inc_lines, &inc_line_nums, NULL);
352+
linecxt = tokenize_file(inc_fullname, inc_file, &inc_lines);
341353

342354
FreeFile(inc_file);
343355
pfree(inc_fullname);
344356

357+
/* Copy all tokens found in the file and append to the tokens list */
345358
foreach(inc_line, inc_lines)
346359
{
347-
List *inc_fields = lfirst(inc_line);
360+
TokenizedLine *tok_line = (TokenizedLine *) lfirst(inc_line);
348361
ListCell *inc_field;
349362

350-
foreach(inc_field, inc_fields)
363+
foreach(inc_field, tok_line->fields)
351364
{
352365
List *inc_tokens = lfirst(inc_field);
353366
ListCell *inc_token;
@@ -366,23 +379,18 @@ tokenize_inc_file(List *tokens,
366379
}
367380

368381
/*
369-
* Tokenize the given file, storing the resulting data into three Lists: a
370-
* List of lines, a List of line numbers, and a List of raw line contents.
382+
* Tokenize the given file.
371383
*
372-
* The list of lines is a triple-nested List structure. Each line is a List of
373-
* fields, and each field is a List of HbaTokens.
384+
* The output is a list of TokenizedLine structs; see struct definition above.
374385
*
375386
* filename must be the absolute path to the target file.
376387
*
377388
* Return value is a memory context which contains all memory allocated by
378-
* this function.
389+
* this function (it's a child of caller's context).
379390
*/
380391
static MemoryContext
381-
tokenize_file(const char *filename, FILE *file,
382-
List **lines, List **line_nums, List **raw_lines)
392+
tokenize_file(const char *filename, FILE *file, List **tok_lines)
383393
{
384-
List *current_line = NIL;
385-
List *current_field = NIL;
386394
int line_number = 1;
387395
MemoryContext linecxt;
388396
MemoryContext oldcxt;
@@ -392,12 +400,13 @@ tokenize_file(const char *filename, FILE *file,
392400
ALLOCSET_SMALL_SIZES);
393401
oldcxt = MemoryContextSwitchTo(linecxt);
394402

395-
*lines = *line_nums = NIL;
403+
*tok_lines = NIL;
396404

397405
while (!feof(file) && !ferror(file))
398406
{
399407
char rawline[MAX_LINE];
400408
char *lineptr;
409+
List *current_line = NIL;
401410

402411
if (!fgets(rawline, sizeof(rawline), file))
403412
break;
@@ -414,32 +423,30 @@ tokenize_file(const char *filename, FILE *file,
414423
while (lineptr >= rawline && (*lineptr == '\n' || *lineptr == '\r'))
415424
*lineptr-- = '\0';
416425

426+
/* Parse fields */
417427
lineptr = rawline;
418-
while (strlen(lineptr) > 0)
428+
while (*lineptr)
419429
{
430+
List *current_field;
431+
420432
current_field = next_field_expand(filename, &lineptr);
433+
/* add field to line, unless we are at EOL or comment start */
434+
if (current_field != NIL)
435+
current_line = lappend(current_line, current_field);
436+
}
421437

422-
/* add tokens to list, unless we are at EOL or comment start */
423-
if (list_length(current_field) > 0)
424-
{
425-
if (current_line == NIL)
426-
{
427-
/* make a new line List, record its line number */
428-
current_line = lappend(current_line, current_field);
429-
*lines = lappend(*lines, current_line);
430-
*line_nums = lappend_int(*line_nums, line_number);
431-
if (raw_lines)
432-
*raw_lines = lappend(*raw_lines, pstrdup(rawline));
433-
}
434-
else
435-
{
436-
/* append tokens to current line's list */
437-
current_line = lappend(current_line, current_field);
438-
}
439-
}
438+
/* Reached EOL; emit line to TokenizedLine list unless it's boring */
439+
if (current_line != NIL)
440+
{
441+
TokenizedLine *tok_line;
442+
443+
tok_line = (TokenizedLine *) palloc(sizeof(TokenizedLine));
444+
tok_line->fields = current_line;
445+
tok_line->line_num = line_number;
446+
tok_line->raw_line = pstrdup(rawline);
447+
*tok_lines = lappend(*tok_lines, tok_line);
440448
}
441-
/* we are at real or logical EOL, so force a new line List */
442-
current_line = NIL;
449+
443450
line_number++;
444451
}
445452

@@ -789,7 +796,7 @@ check_same_host_or_net(SockAddr *raddr, IPCompareMethod method)
789796
ereport(LOG, \
790797
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
791798
errmsg("missing entry in file \"%s\" at end of line %d", \
792-
IdentFileName, line_number))); \
799+
IdentFileName, line_num))); \
793800
return NULL; \
794801
} \
795802
} while (0);
@@ -800,26 +807,26 @@ check_same_host_or_net(SockAddr *raddr, IPCompareMethod method)
800807
(errcode(ERRCODE_CONFIG_FILE_ERROR), \
801808
errmsg("multiple values in ident field"), \
802809
errcontext("line %d of configuration file \"%s\"", \
803-
line_number, IdentFileName))); \
810+
line_num, IdentFileName))); \
804811
return NULL; \
805812
} \
806813
} while (0);
807814

808815

809816
/*
810817
* Parse one tokenised line from the hba config file and store the result in a
811-
* HbaLine structure, or NULL if parsing fails.
818+
* HbaLine structure.
812819
*
813-
* The tokenised line is a List of fields, each field being a List of
814-
* HbaTokens.
820+
* Return NULL if parsing fails.
815821
*
816822
* Note: this function leaks memory when an error occurs. Caller is expected
817823
* to have set a memory context that will be reset if this function returns
818824
* NULL.
819825
*/
820826
static HbaLine *
821-
parse_hba_line(List *line, int line_num, char *raw_line)
827+
parse_hba_line(TokenizedLine *tok_line)
822828
{
829+
int line_num = tok_line->line_num;
823830
char *str;
824831
struct addrinfo *gai_result;
825832
struct addrinfo hints;
@@ -834,10 +841,11 @@ parse_hba_line(List *line, int line_num, char *raw_line)
834841

835842
parsedline = palloc0(sizeof(HbaLine));
836843
parsedline->linenumber = line_num;
837-
parsedline->rawline = pstrdup(raw_line);
844+
parsedline->rawline = pstrdup(tok_line->raw_line);
838845

839846
/* Check the record type. */
840-
field = list_head(line);
847+
Assert(tok_line->fields != NIL);
848+
field = list_head(tok_line->fields);
841849
tokens = lfirst(field);
842850
if (tokens->length > 1)
843851
{
@@ -1769,11 +1777,7 @@ load_hba(void)
17691777
{
17701778
FILE *file;
17711779
List *hba_lines = NIL;
1772-
List *hba_line_nums = NIL;
1773-
List *hba_raw_lines = NIL;
1774-
ListCell *line,
1775-
*line_num,
1776-
*raw_line;
1780+
ListCell *line;
17771781
List *new_parsed_lines = NIL;
17781782
bool ok = true;
17791783
MemoryContext linecxt;
@@ -1790,7 +1794,7 @@ load_hba(void)
17901794
return false;
17911795
}
17921796

1793-
linecxt = tokenize_file(HbaFileName, file, &hba_lines, &hba_line_nums, &hba_raw_lines);
1797+
linecxt = tokenize_file(HbaFileName, file, &hba_lines);
17941798
FreeFile(file);
17951799

17961800
/* Now parse all the lines */
@@ -1799,11 +1803,12 @@ load_hba(void)
17991803
"hba parser context",
18001804
ALLOCSET_SMALL_SIZES);
18011805
oldcxt = MemoryContextSwitchTo(hbacxt);
1802-
forthree(line, hba_lines, line_num, hba_line_nums, raw_line, hba_raw_lines)
1806+
foreach(line, hba_lines)
18031807
{
1808+
TokenizedLine *tok_line = (TokenizedLine *) lfirst(line);
18041809
HbaLine *newline;
18051810

1806-
if ((newline = parse_hba_line(lfirst(line), lfirst_int(line_num), lfirst(raw_line))) == NULL)
1811+
if ((newline = parse_hba_line(tok_line)) == NULL)
18071812
{
18081813
/*
18091814
* Parse error in the file, so indicate there's a problem. NB: a
@@ -1861,9 +1866,9 @@ load_hba(void)
18611866

18621867
/*
18631868
* Parse one tokenised line from the ident config file and store the result in
1864-
* an IdentLine structure, or NULL if parsing fails.
1869+
* an IdentLine structure.
18651870
*
1866-
* The tokenised line is a nested List of fields and tokens.
1871+
* Return NULL if parsing fails.
18671872
*
18681873
* If ident_user is a regular expression (ie. begins with a slash), it is
18691874
* compiled and stored in IdentLine structure.
@@ -1873,18 +1878,19 @@ load_hba(void)
18731878
* NULL.
18741879
*/
18751880
static IdentLine *
1876-
parse_ident_line(List *line, int line_number)
1881+
parse_ident_line(TokenizedLine *tok_line)
18771882
{
1883+
int line_num = tok_line->line_num;
18781884
ListCell *field;
18791885
List *tokens;
18801886
HbaToken *token;
18811887
IdentLine *parsedline;
18821888

1883-
Assert(line != NIL);
1884-
field = list_head(line);
1889+
Assert(tok_line->fields != NIL);
1890+
field = list_head(tok_line->fields);
18851891

18861892
parsedline = palloc0(sizeof(IdentLine));
1887-
parsedline->linenumber = line_number;
1893+
parsedline->linenumber = line_num;
18881894

18891895
/* Get the map token (must exist) */
18901896
tokens = lfirst(field);
@@ -2144,9 +2150,7 @@ load_ident(void)
21442150
{
21452151
FILE *file;
21462152
List *ident_lines = NIL;
2147-
List *ident_line_nums = NIL;
21482153
ListCell *line_cell,
2149-
*num_cell,
21502154
*parsed_line_cell;
21512155
List *new_parsed_lines = NIL;
21522156
bool ok = true;
@@ -2166,7 +2170,7 @@ load_ident(void)
21662170
return false;
21672171
}
21682172

2169-
linecxt = tokenize_file(IdentFileName, file, &ident_lines, &ident_line_nums, NULL);
2173+
linecxt = tokenize_file(IdentFileName, file, &ident_lines);
21702174
FreeFile(file);
21712175

21722176
/* Now parse all the lines */
@@ -2175,9 +2179,11 @@ load_ident(void)
21752179
"ident parser context",
21762180
ALLOCSET_SMALL_SIZES);
21772181
oldcxt = MemoryContextSwitchTo(ident_context);
2178-
forboth(line_cell, ident_lines, num_cell, ident_line_nums)
2182+
foreach(line_cell, ident_lines)
21792183
{
2180-
if ((newline = parse_ident_line(lfirst(line_cell), lfirst_int(num_cell))) == NULL)
2184+
TokenizedLine *tok_line = (TokenizedLine *) lfirst(line_cell);
2185+
2186+
if ((newline = parse_ident_line(tok_line)) == NULL)
21812187
{
21822188
/*
21832189
* Parse error in the file, so indicate there's a problem. Free

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy