From 47980dc47b81ff2453465ac17f2816f522481405 Mon Sep 17 00:00:00 2001 From: Georgios Kokolatos Date: Fri, 7 Aug 2020 11:16:53 +0530 Subject: [PATCH v2] Use a stringInfo instead of a char for replace_string in pg_regress The exposed function replase_string() in pg_regress assumes that there exists enough space in the string it operates on. While this is documented and expected, the consequence can be subtle failures in the tests which might be hard to trace back to the root cause. Provide an alternative function that operates on a StringInfo instead. Co-authored-by: Asim R P --- src/test/regress/pg_regress.c | 52 +++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index d82e0189dcf..3fe620ef476 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -33,6 +33,7 @@ #include "common/restricted_token.h" #include "common/username.h" #include "getopt_long.h" +#include "lib/stringinfo.h" #include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */ #include "pg_config_paths.h" #include "pg_regress.h" @@ -454,6 +455,27 @@ replace_string(char *string, const char *replace, const char *replacement) } } +/* + * Replace all occurrences of a string in a stringInfo with a different string. + */ +static void +replace_stringInfo(StringInfo string, const char *replace, const char *replacement) +{ + char *ptr; + + while ((ptr = strstr(string->data, replace)) != NULL) + { + char *suffix = pnstrdup(ptr + strlen(replace), string->maxlen); + size_t pos = ptr - string->data; + + string->len = pos; + appendStringInfoString(string, replacement); + appendStringInfoString(string, suffix); + + free(suffix); + } +} + /* * Convert *.source found in the "source" directory, replacing certain tokens * in the file contents with their intended values, and put the resulting files @@ -521,7 +543,7 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch char prefix[MAXPGPATH]; FILE *infile, *outfile; - char line[1024]; + StringInfoData line; /* reject filenames not finishing in ".source" */ if (strlen(*name) < 8) @@ -551,15 +573,29 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch progname, destfile, strerror(errno)); exit(2); } - while (fgets(line, sizeof(line), infile)) + + initStringInfo(&line); + + while (!feof(infile)) { - replace_string(line, "@abs_srcdir@", inputdir); - replace_string(line, "@abs_builddir@", outputdir); - replace_string(line, "@testtablespace@", testtablespace); - replace_string(line, "@libdir@", dlpath); - replace_string(line, "@DLSUFFIX@", DLSUFFIX); - fputs(line, outfile); + /* Read one line in StringInfo */ + char c; + while ((c = fgetc(infile)) != EOF) + { + appendStringInfoChar(&line, c); + if (c == '\n') + break; + } + + replace_stringInfo(&line, "@abs_srcdir@", inputdir); + replace_stringInfo(&line, "@abs_builddir@", outputdir); + replace_stringInfo(&line, "@testtablespace@", testtablespace); + replace_stringInfo(&line, "@libdir@", dlpath); + replace_stringInfo(&line, "@DLSUFFIX@", DLSUFFIX); + fputs(line.data, outfile); + resetStringInfo(&line); } + pfree(line.data); fclose(infile); fclose(outfile); } -- 2.24.2 (Apple Git-127)