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

Commit784b1ba

Browse files
committed
Remove arbitrary line length limits in pg_regress (plain and ECPG).
Refactor replace_string() to use a StringInfo for the modifiablestring argument. This allows the string to be of indefinite sizeinitially and/or grow substantially during replacement. The previouslogic in convert_sourcefiles_in() had a hard-wired limit of 1024bytes on any line in input/*.sql or output/*.out files. While we'venot had reports of trouble yet, it'd surely have bit us someday.This also fixes replace_string() so it won't get into an infiniteloop if the string-to-be-replaced is a substring of the replacement.That's unlikely to happen in current usage, but the function surelyshouldn't depend on it.Also fix ecpg_filter() to use a StringInfo and thereby remove itshard limit of 300 bytes on the length of an ecpg source line.Asim Rama Praveen and Georgios Kokolatos,reviewed by Alvaro Herrera and myselfDiscussion:https://postgr.es/m/y9Dlk2QhiZ39DhaB1QE9mgZ95HcOQKZCNtGwN7XCRKMdBRBnX_0woaRUtTjloEp4PKA6ERmcUcfq3lPGfKPOJ5xX2TV-5WoRYyySeNHRzdw=@protonmail.com
1 parent8e3c58e commit784b1ba

File tree

3 files changed

+77
-56
lines changed

3 files changed

+77
-56
lines changed

‎src/interfaces/ecpg/test/pg_regress_ecpg.c‎

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
#include"postgres_fe.h"
2020

2121
#include"pg_regress.h"
22+
#include"common/string.h"
23+
#include"lib/stringinfo.h"
2224

23-
#defineLINEBUFSIZE 300
2425

2526
staticvoid
2627
ecpg_filter(constchar*sourcefile,constchar*outfile)
@@ -31,7 +32,7 @@ ecpg_filter(const char *sourcefile, const char *outfile)
3132
*/
3233
FILE*s,
3334
*t;
34-
charlinebuf[LINEBUFSIZE];
35+
StringInfoDatalinebuf;
3536

3637
s=fopen(sourcefile,"r");
3738
if (!s)
@@ -46,13 +47,14 @@ ecpg_filter(const char *sourcefile, const char *outfile)
4647
exit(2);
4748
}
4849

49-
while (fgets(linebuf,LINEBUFSIZE,s))
50+
initStringInfo(&linebuf);
51+
52+
while (pg_get_line_append(s,&linebuf))
5053
{
5154
/* check for "#line " in the beginning */
52-
if (strstr(linebuf,"#line ")==linebuf)
55+
if (strstr(linebuf.data,"#line ")==linebuf.data)
5356
{
54-
char*p=strchr(linebuf,'"');
55-
char*n;
57+
char*p=strchr(linebuf.data,'"');
5658
intplen=1;
5759

5860
while (*p&& (*(p+plen)=='.'||strchr(p+plen,'/')!=NULL))
@@ -62,13 +64,15 @@ ecpg_filter(const char *sourcefile, const char *outfile)
6264
/* plen is one more than the number of . and / characters */
6365
if (plen>1)
6466
{
65-
n= (char*)malloc(plen);
66-
strlcpy(n,p+1,plen);
67-
replace_string(linebuf,n,"");
67+
memmove(p+1,p+plen,strlen(p+plen)+1);
68+
/* we don't bother to fix up linebuf.len */
6869
}
6970
}
70-
fputs(linebuf,t);
71+
fputs(linebuf.data,t);
72+
resetStringInfo(&linebuf);
7173
}
74+
75+
pfree(linebuf.data);
7276
fclose(s);
7377
fclose(t);
7478
}
@@ -87,40 +91,42 @@ ecpg_start_test(const char *testname,
8791
PID_TYPEpid;
8892
charinprg[MAXPGPATH];
8993
charinsource[MAXPGPATH];
90-
char*outfile_stdout,
94+
StringInfoDatatestname_dash;
95+
charoutfile_stdout[MAXPGPATH],
9196
expectfile_stdout[MAXPGPATH];
92-
char*outfile_stderr,
97+
charoutfile_stderr[MAXPGPATH],
9398
expectfile_stderr[MAXPGPATH];
94-
char*outfile_source,
99+
charoutfile_source[MAXPGPATH],
95100
expectfile_source[MAXPGPATH];
96101
charcmd[MAXPGPATH*3];
97-
char*testname_dash;
98102
char*appnameenv;
99103

100104
snprintf(inprg,sizeof(inprg),"%s/%s",inputdir,testname);
105+
snprintf(insource,sizeof(insource),"%s.c",testname);
106+
107+
initStringInfo(&testname_dash);
108+
appendStringInfoString(&testname_dash,testname);
109+
replace_string(&testname_dash,"/","-");
101110

102-
testname_dash=strdup(testname);
103-
replace_string(testname_dash,"/","-");
104111
snprintf(expectfile_stdout,sizeof(expectfile_stdout),
105112
"%s/expected/%s.stdout",
106-
outputdir,testname_dash);
113+
outputdir,testname_dash.data);
107114
snprintf(expectfile_stderr,sizeof(expectfile_stderr),
108115
"%s/expected/%s.stderr",
109-
outputdir,testname_dash);
116+
outputdir,testname_dash.data);
110117
snprintf(expectfile_source,sizeof(expectfile_source),
111118
"%s/expected/%s.c",
112-
outputdir,testname_dash);
113-
114-
/*
115-
* We can use replace_string() here because the replacement string does
116-
* not occupy more space than the replaced one.
117-
*/
118-
outfile_stdout=strdup(expectfile_stdout);
119-
replace_string(outfile_stdout,"/expected/","/results/");
120-
outfile_stderr=strdup(expectfile_stderr);
121-
replace_string(outfile_stderr,"/expected/","/results/");
122-
outfile_source=strdup(expectfile_source);
123-
replace_string(outfile_source,"/expected/","/results/");
119+
outputdir,testname_dash.data);
120+
121+
snprintf(outfile_stdout,sizeof(outfile_stdout),
122+
"%s/results/%s.stdout",
123+
outputdir,testname_dash.data);
124+
snprintf(outfile_stderr,sizeof(outfile_stderr),
125+
"%s/results/%s.stderr",
126+
outputdir,testname_dash.data);
127+
snprintf(outfile_source,sizeof(outfile_source),
128+
"%s/results/%s.c",
129+
outputdir,testname_dash.data);
124130

125131
add_stringlist_item(resultfiles,outfile_stdout);
126132
add_stringlist_item(expectfiles,expectfile_stdout);
@@ -134,18 +140,15 @@ ecpg_start_test(const char *testname,
134140
add_stringlist_item(expectfiles,expectfile_source);
135141
add_stringlist_item(tags,"source");
136142

137-
snprintf(insource,sizeof(insource),"%s.c",testname);
138143
ecpg_filter(insource,outfile_source);
139144

140-
snprintf(inprg,sizeof(inprg),"%s/%s",inputdir,testname);
141-
142145
snprintf(cmd,sizeof(cmd),
143146
"\"%s\" >\"%s\" 2>\"%s\"",
144147
inprg,
145148
outfile_stdout,
146149
outfile_stderr);
147150

148-
appnameenv=psprintf("PGAPPNAME=ecpg/%s",testname_dash);
151+
appnameenv=psprintf("PGAPPNAME=ecpg/%s",testname_dash.data);
149152
putenv(appnameenv);
150153

151154
pid=spawn_process(cmd);
@@ -160,10 +163,7 @@ ecpg_start_test(const char *testname,
160163
unsetenv("PGAPPNAME");
161164
free(appnameenv);
162165

163-
free(testname_dash);
164-
free(outfile_stdout);
165-
free(outfile_stderr);
166-
free(outfile_source);
166+
free(testname_dash.data);
167167

168168
returnpid;
169169
}

‎src/test/regress/pg_regress.c‎

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131

3232
#include"common/logging.h"
3333
#include"common/restricted_token.h"
34+
#include"common/string.h"
3435
#include"common/username.h"
3536
#include"getopt_long.h"
37+
#include"lib/stringinfo.h"
3638
#include"libpq/pqcomm.h"/* needed for UNIXSOCK_PATH() */
3739
#include"pg_config_paths.h"
3840
#include"pg_regress.h"
@@ -435,22 +437,32 @@ string_matches_pattern(const char *str, const char *pattern)
435437
}
436438

437439
/*
438-
* Replace all occurrences of a string in a string with a different string.
439-
* NOTE: Assumes there is enough room in the target buffer!
440+
* Replace all occurrences of "replace" in "string" with "replacement".
441+
* The StringInfo will be suitably enlarged if necessary.
442+
*
443+
* Note: this is optimized on the assumption that most calls will find
444+
* no more than one occurrence of "replace", and quite likely none.
440445
*/
441446
void
442-
replace_string(char*string,constchar*replace,constchar*replacement)
447+
replace_string(StringInfostring,constchar*replace,constchar*replacement)
443448
{
449+
intpos=0;
444450
char*ptr;
445451

446-
while ((ptr=strstr(string,replace))!=NULL)
452+
while ((ptr=strstr(string->data+pos,replace))!=NULL)
447453
{
448-
char*dup=pg_strdup(string);
454+
/* Must copy the remainder of the string out of the StringInfo */
455+
char*suffix=pg_strdup(ptr+strlen(replace));
449456

450-
strlcpy(string,dup,ptr-string+1);
451-
strcat(string,replacement);
452-
strcat(string,dup+ (ptr-string)+strlen(replace));
453-
free(dup);
457+
/* Truncate StringInfo at start of found string ... */
458+
string->len=ptr-string->data;
459+
/* ... and append the replacement (this restores the trailing '\0') */
460+
appendStringInfoString(string,replacement);
461+
/* Next search should start after the replacement */
462+
pos=string->len;
463+
/* Put back the remainder of the string */
464+
appendStringInfoString(string,suffix);
465+
free(suffix);
454466
}
455467
}
456468

@@ -521,7 +533,7 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch
521533
charprefix[MAXPGPATH];
522534
FILE*infile,
523535
*outfile;
524-
charline[1024];
536+
StringInfoDataline;
525537

526538
/* reject filenames not finishing in ".source" */
527539
if (strlen(*name)<8)
@@ -551,15 +563,21 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch
551563
progname,destfile,strerror(errno));
552564
exit(2);
553565
}
554-
while (fgets(line,sizeof(line),infile))
566+
567+
initStringInfo(&line);
568+
569+
while (pg_get_line_append(infile,&line))
555570
{
556-
replace_string(line,"@abs_srcdir@",inputdir);
557-
replace_string(line,"@abs_builddir@",outputdir);
558-
replace_string(line,"@testtablespace@",testtablespace);
559-
replace_string(line,"@libdir@",dlpath);
560-
replace_string(line,"@DLSUFFIX@",DLSUFFIX);
561-
fputs(line,outfile);
571+
replace_string(&line,"@abs_srcdir@",inputdir);
572+
replace_string(&line,"@abs_builddir@",outputdir);
573+
replace_string(&line,"@testtablespace@",testtablespace);
574+
replace_string(&line,"@libdir@",dlpath);
575+
replace_string(&line,"@DLSUFFIX@",DLSUFFIX);
576+
fputs(line.data,outfile);
577+
resetStringInfo(&line);
562578
}
579+
580+
pfree(line.data);
563581
fclose(infile);
564582
fclose(outfile);
565583
}

‎src/test/regress/pg_regress.h‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#defineINVALID_PID INVALID_HANDLE_VALUE
1919
#endif
2020

21+
structStringInfoData;/* avoid including stringinfo.h here */
22+
2123
/* simple list of strings */
2224
typedefstruct_stringlist
2325
{
@@ -49,5 +51,6 @@ intregression_main(int argc, char *argv[],
4951
init_functionifunc,test_functiontfunc);
5052
voidadd_stringlist_item(_stringlist**listhead,constchar*str);
5153
PID_TYPEspawn_process(constchar*cmdline);
52-
voidreplace_string(char*string,constchar*replace,constchar*replacement);
54+
voidreplace_string(structStringInfoData*string,
55+
constchar*replace,constchar*replacement);
5356
boolfile_exists(constchar*file);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp