Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfc6da31

Browse files
committed
Rewrite ProcessConfigFile() to avoid misbehavior at EOF, as per report
from Andrus Moor. The former state-machine-style coding wasn't actuallydoing much except obscuring the control flow, and it didn't extendreadily to fix this case, so I just took it out. Also, add aYY_FLUSH_BUFFER call to ensure the lexer is reset correctly if theprevious scan failed partway through the file.
1 parent0898033 commitfc6da31

File tree

1 file changed

+77
-78
lines changed

1 file changed

+77
-78
lines changed

‎src/backend/utils/misc/guc-file.l

Lines changed: 77 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
66
*
7-
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.32 2005/09/21 20:33:34 tgl Exp $
7+
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.33 2006/01/01 19:52:40 tgl Exp $
88
*/
99

1010
%{
@@ -126,7 +126,7 @@ void
126126
ProcessConfigFile(GucContext context)
127127
{
128128
intelevel;
129-
inttoken, parse_state;
129+
inttoken;
130130
char *opt_name, *opt_value;
131131
struct name_value_pair *item, *head, *tail;
132132
FILE *fp;
@@ -144,109 +144,108 @@ ProcessConfigFile(GucContext context)
144144
else
145145
elevel = ERROR;
146146
147-
fp = AllocateFile(ConfigFileName, "r");
148-
if (!fp)
149-
{
147+
fp = AllocateFile(ConfigFileName, "r");
148+
if (!fp)
149+
{
150150
ereport(elevel,
151151
(errcode_for_file_access(),
152152
errmsg("could not open configuration file\"%s\": %m",
153153
ConfigFileName)));
154154
return;
155-
}
155+
}
156156
157157
/*
158158
* Parse
159159
*/
160160
yyin = fp;
161-
parse_state = 0;
161+
YY_FLUSH_BUFFER;/* in case we abandoned a prior scan */
162162
head = tail = NULL;
163163
opt_name = opt_value = NULL;
164164
ConfigFileLineno = 1;
165165
166-
while ((token = yylex()))
166+
/* This loop iterates once per logical line */
167+
while ((token = yylex()))
167168
{
168-
switch(parse_state)
169-
{
170-
case 0: /* no previous input */
171-
if (token == GUC_EOL) /* empty line */
172-
continue;
173-
if (token != GUC_ID && token != GUC_QUALIFIED_ID)
174-
goto parse_error;
175-
opt_name = pstrdup(yytext);
176-
parse_state = 1;
177-
break;
178-
179-
case 1: /* found name */
180-
/* ignore equals sign */
181-
if (token == GUC_EQUALS)
182-
token = yylex();
183-
184-
if (token != GUC_ID &&
185-
token != GUC_STRING &&
186-
token != GUC_INTEGER &&
187-
token != GUC_REAL &&
188-
token != GUC_UNQUOTED_STRING)
189-
goto parse_error;
190-
if (token == GUC_STRING)/* strip quotes and escapes */
191-
opt_value = GUC_scanstr(yytext);
192-
else
193-
opt_value = pstrdup(yytext);
194-
parse_state = 2;
195-
break;
196-
197-
case 2: /* now we'd like an end of line*/
198-
if (token != GUC_EOL)
199-
goto parse_error;
200-
201-
if (strcmp(opt_name,"custom_variable_classes") ==0)
202-
{
203-
/*
204-
* This variable must be processed first as it controls
205-
* the validity of other variables; so apply immediately.
206-
*/
207-
if (!set_config_option(opt_name, opt_value, context,
208-
PGC_S_FILE,false,true))
209-
{
210-
pfree(opt_name);
211-
pfree(opt_value);
212-
FreeFile(fp);
213-
goto cleanup_exit;
214-
}
215-
pfree(opt_name);
216-
pfree(opt_value);
217-
}
218-
else
219-
{
220-
/* append to list */
221-
item =palloc(sizeof *item);
222-
item->name = opt_name;
223-
item->value = opt_value;
224-
item->next =NULL;
225-
if (!head)
226-
head = item;
227-
else
228-
tail->next = item;
229-
tail = item;
230-
}
231-
232-
parse_state =0;
233-
break;
234-
}
169+
if (token == GUC_EOL)/* empty or comment line */
170+
continue;
171+
172+
/* first token on line is option name */
173+
if (token != GUC_ID && token != GUC_QUALIFIED_ID)
174+
goto parse_error;
175+
opt_name = pstrdup(yytext);
176+
177+
/* next we have an optional equal sign; discard if present */
178+
token = yylex();
179+
if (token == GUC_EQUALS)
180+
token = yylex();
181+
182+
/* now we must have the option value */
183+
if (token != GUC_ID &&
184+
token != GUC_STRING &&
185+
token != GUC_INTEGER &&
186+
token != GUC_REAL &&
187+
token != GUC_UNQUOTED_STRING)
188+
goto parse_error;
189+
if (token == GUC_STRING)/* strip quotes and escapes */
190+
opt_value = GUC_scanstr(yytext);
191+
else
192+
opt_value = pstrdup(yytext);
193+
194+
/* now we'd like an end of line,or possibly EOF*/
195+
token = yylex();
196+
if (token != GUC_EOL && token !=0)
197+
goto parse_error;
198+
199+
/* OK, save the option name and value */
200+
if (strcmp(opt_name,"custom_variable_classes") ==0)
201+
{
202+
/*
203+
* This variable must be processed first as it controls
204+
* the validity of other variables; so apply immediately.
205+
*/
206+
if (!set_config_option(opt_name, opt_value, context,
207+
PGC_S_FILE,false,true))
208+
{
209+
pfree(opt_name);
210+
pfree(opt_value);
211+
FreeFile(fp);
212+
goto cleanup_exit;
213+
}
214+
pfree(opt_name);
215+
pfree(opt_value);
216+
}
217+
else
218+
{
219+
/* append to list */
220+
item =palloc(sizeof *item);
221+
item->name = opt_name;
222+
item->value = opt_value;
223+
item->next =NULL;
224+
if (!head)
225+
head = item;
226+
else
227+
tail->next = item;
228+
tail = item;
229+
}
230+
231+
/* break out of loop if read EOF, else loop for next line */
232+
if (token ==0)
233+
break;
235234
}
236235

237236
FreeFile(fp);
238237

239238
/*
240239
* Check if all options are valid
241240
*/
242-
for(item = head; item; item=item->next)
241+
for(item = head; item; item=item->next)
243242
{
244243
if (!set_config_option(item->name, item->value, context,
245244
PGC_S_FILE,false,false))
246245
goto cleanup_exit;
247246
}
248247

249-
/* If we got here all the options parsed okay, so apply them. */
248+
/* If we got here all the options parsed okay, so apply them. */
250249
for(item = head; item; item=item->next)
251250
{
252251
set_config_option(item->name, item->value, context,
@@ -260,7 +259,7 @@ ProcessConfigFile(GucContext context)
260259
parse_error:
261260
FreeFile(fp);
262261
free_name_value_list(head);
263-
if (token == GUC_EOL)
262+
if (token == GUC_EOL || token ==0)
264263
ereport(elevel,
265264
(errcode(ERRCODE_SYNTAX_ERROR),
266265
errmsg("syntax error in file\"%s\" line %u, near end of line",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp