mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Remove arbitrary line length limits in pg_regress (plain and ECPG).
Refactor replace_string() to use a StringInfo for the modifiable string argument. This allows the string to be of indefinite size initially and/or grow substantially during replacement. The previous logic in convert_sourcefiles_in() had a hard-wired limit of 1024 bytes on any line in input/*.sql or output/*.out files. While we've not had reports of trouble yet, it'd surely have bit us someday. This also fixes replace_string() so it won't get into an infinite loop if the string-to-be-replaced is a substring of the replacement. That's unlikely to happen in current usage, but the function surely shouldn't depend on it. Also fix ecpg_filter() to use a StringInfo and thereby remove its hard limit of 300 bytes on the length of an ecpg source line. Asim Rama Praveen and Georgios Kokolatos, reviewed by Alvaro Herrera and myself Discussion: https://postgr.es/m/y9Dlk2QhiZ39DhaB1QE9mgZ95HcOQKZCNtGwN7XCRKMdBRBnX_0woaRUtTjloEp4PKA6ERmcUcfq3lPGfKPOJ5xX2TV-5WoRYyySeNHRzdw=@protonmail.com
This commit is contained in:
@ -19,8 +19,9 @@
|
||||
#include "postgres_fe.h"
|
||||
|
||||
#include "pg_regress.h"
|
||||
#include "common/string.h"
|
||||
#include "lib/stringinfo.h"
|
||||
|
||||
#define LINEBUFSIZE 300
|
||||
|
||||
static void
|
||||
ecpg_filter(const char *sourcefile, const char *outfile)
|
||||
@ -31,7 +32,7 @@ ecpg_filter(const char *sourcefile, const char *outfile)
|
||||
*/
|
||||
FILE *s,
|
||||
*t;
|
||||
char linebuf[LINEBUFSIZE];
|
||||
StringInfoData linebuf;
|
||||
|
||||
s = fopen(sourcefile, "r");
|
||||
if (!s)
|
||||
@ -46,13 +47,14 @@ ecpg_filter(const char *sourcefile, const char *outfile)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
while (fgets(linebuf, LINEBUFSIZE, s))
|
||||
initStringInfo(&linebuf);
|
||||
|
||||
while (pg_get_line_append(s, &linebuf))
|
||||
{
|
||||
/* check for "#line " in the beginning */
|
||||
if (strstr(linebuf, "#line ") == linebuf)
|
||||
if (strstr(linebuf.data, "#line ") == linebuf.data)
|
||||
{
|
||||
char *p = strchr(linebuf, '"');
|
||||
char *n;
|
||||
char *p = strchr(linebuf.data, '"');
|
||||
int plen = 1;
|
||||
|
||||
while (*p && (*(p + plen) == '.' || strchr(p + plen, '/') != NULL))
|
||||
@ -62,13 +64,15 @@ ecpg_filter(const char *sourcefile, const char *outfile)
|
||||
/* plen is one more than the number of . and / characters */
|
||||
if (plen > 1)
|
||||
{
|
||||
n = (char *) malloc(plen);
|
||||
strlcpy(n, p + 1, plen);
|
||||
replace_string(linebuf, n, "");
|
||||
memmove(p + 1, p + plen, strlen(p + plen) + 1);
|
||||
/* we don't bother to fix up linebuf.len */
|
||||
}
|
||||
}
|
||||
fputs(linebuf, t);
|
||||
fputs(linebuf.data, t);
|
||||
resetStringInfo(&linebuf);
|
||||
}
|
||||
|
||||
pfree(linebuf.data);
|
||||
fclose(s);
|
||||
fclose(t);
|
||||
}
|
||||
@ -87,40 +91,42 @@ ecpg_start_test(const char *testname,
|
||||
PID_TYPE pid;
|
||||
char inprg[MAXPGPATH];
|
||||
char insource[MAXPGPATH];
|
||||
char *outfile_stdout,
|
||||
StringInfoData testname_dash;
|
||||
char outfile_stdout[MAXPGPATH],
|
||||
expectfile_stdout[MAXPGPATH];
|
||||
char *outfile_stderr,
|
||||
char outfile_stderr[MAXPGPATH],
|
||||
expectfile_stderr[MAXPGPATH];
|
||||
char *outfile_source,
|
||||
char outfile_source[MAXPGPATH],
|
||||
expectfile_source[MAXPGPATH];
|
||||
char cmd[MAXPGPATH * 3];
|
||||
char *testname_dash;
|
||||
char *appnameenv;
|
||||
|
||||
snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
|
||||
snprintf(insource, sizeof(insource), "%s.c", testname);
|
||||
|
||||
initStringInfo(&testname_dash);
|
||||
appendStringInfoString(&testname_dash, testname);
|
||||
replace_string(&testname_dash, "/", "-");
|
||||
|
||||
testname_dash = strdup(testname);
|
||||
replace_string(testname_dash, "/", "-");
|
||||
snprintf(expectfile_stdout, sizeof(expectfile_stdout),
|
||||
"%s/expected/%s.stdout",
|
||||
outputdir, testname_dash);
|
||||
outputdir, testname_dash.data);
|
||||
snprintf(expectfile_stderr, sizeof(expectfile_stderr),
|
||||
"%s/expected/%s.stderr",
|
||||
outputdir, testname_dash);
|
||||
outputdir, testname_dash.data);
|
||||
snprintf(expectfile_source, sizeof(expectfile_source),
|
||||
"%s/expected/%s.c",
|
||||
outputdir, testname_dash);
|
||||
outputdir, testname_dash.data);
|
||||
|
||||
/*
|
||||
* We can use replace_string() here because the replacement string does
|
||||
* not occupy more space than the replaced one.
|
||||
*/
|
||||
outfile_stdout = strdup(expectfile_stdout);
|
||||
replace_string(outfile_stdout, "/expected/", "/results/");
|
||||
outfile_stderr = strdup(expectfile_stderr);
|
||||
replace_string(outfile_stderr, "/expected/", "/results/");
|
||||
outfile_source = strdup(expectfile_source);
|
||||
replace_string(outfile_source, "/expected/", "/results/");
|
||||
snprintf(outfile_stdout, sizeof(outfile_stdout),
|
||||
"%s/results/%s.stdout",
|
||||
outputdir, testname_dash.data);
|
||||
snprintf(outfile_stderr, sizeof(outfile_stderr),
|
||||
"%s/results/%s.stderr",
|
||||
outputdir, testname_dash.data);
|
||||
snprintf(outfile_source, sizeof(outfile_source),
|
||||
"%s/results/%s.c",
|
||||
outputdir, testname_dash.data);
|
||||
|
||||
add_stringlist_item(resultfiles, outfile_stdout);
|
||||
add_stringlist_item(expectfiles, expectfile_stdout);
|
||||
@ -134,18 +140,15 @@ ecpg_start_test(const char *testname,
|
||||
add_stringlist_item(expectfiles, expectfile_source);
|
||||
add_stringlist_item(tags, "source");
|
||||
|
||||
snprintf(insource, sizeof(insource), "%s.c", testname);
|
||||
ecpg_filter(insource, outfile_source);
|
||||
|
||||
snprintf(inprg, sizeof(inprg), "%s/%s", inputdir, testname);
|
||||
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"\"%s\" >\"%s\" 2>\"%s\"",
|
||||
inprg,
|
||||
outfile_stdout,
|
||||
outfile_stderr);
|
||||
|
||||
appnameenv = psprintf("PGAPPNAME=ecpg/%s", testname_dash);
|
||||
appnameenv = psprintf("PGAPPNAME=ecpg/%s", testname_dash.data);
|
||||
putenv(appnameenv);
|
||||
|
||||
pid = spawn_process(cmd);
|
||||
@ -160,10 +163,7 @@ ecpg_start_test(const char *testname,
|
||||
unsetenv("PGAPPNAME");
|
||||
free(appnameenv);
|
||||
|
||||
free(testname_dash);
|
||||
free(outfile_stdout);
|
||||
free(outfile_stderr);
|
||||
free(outfile_source);
|
||||
free(testname_dash.data);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
Reference in New Issue
Block a user