@@ -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 */
7272typedef 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
97110static MemoryContext tokenize_file (const char * filename , FILE * file ,
98- List * * lines , List * * line_nums , List * * raw_lines );
111+ List * * tok_lines );
99112static List * tokenize_inc_file (List * tokens , const char * outer_filename ,
100113 const char * inc_filename );
101114static 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 */
380391static 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 */
820826static 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 */
18751880static 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