diff --git a/src/backend/libpq/be-secure-common.c b/src/backend/libpq/be-secure-common.c index 4abbef5bf1..e8f27bc782 100644 --- a/src/backend/libpq/be-secure-common.c +++ b/src/backend/libpq/be-secure-common.c @@ -22,6 +22,7 @@ #include #include +#include "common/string.h" #include "libpq/libpq.h" #include "storage/fd.h" @@ -112,11 +113,8 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, goto error; } - /* strip trailing newline, including \r in case we're on Windows */ - len = strlen(buf); - while (len > 0 && (buf[len - 1] == '\n' || - buf[len - 1] == '\r')) - buf[--len] = '\0'; + /* strip trailing newline and carriage return */ + len = pg_strip_crlf(buf); error: pfree(command.data); diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 068b65a2af..dd76be6dd2 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -27,6 +27,7 @@ #include "common/controldata_utils.h" #include "common/file_perm.h" #include "common/logging.h" +#include "common/string.h" #include "getopt_long.h" #include "utils/pidfile.h" @@ -2176,7 +2177,6 @@ adjust_data_dir(void) filename[MAXPGPATH], *my_exec_path; FILE *fd; - int len; /* do nothing if we're working without knowledge of data dir */ if (pg_config == NULL) @@ -2219,12 +2219,8 @@ adjust_data_dir(void) pclose(fd); free(my_exec_path); - /* Remove trailing newline, handling Windows newlines as well */ - len = strlen(filename); - while (len > 0 && - (filename[len - 1] == '\n' || - filename[len - 1] == '\r')) - filename[--len] = '\0'; + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(filename); free(pg_data); pg_data = pg_strdup(filename); diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index 74063ebf2f..159a30b520 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -54,6 +54,7 @@ #include "common/file_perm.h" #include "common/logging.h" #include "common/restricted_token.h" +#include "common/string.h" #include "storage/large_object.h" #include "pg_getopt.h" #include "getopt_long.h" @@ -538,7 +539,6 @@ CheckDataVersion(void) const char *ver_file = "PG_VERSION"; FILE *ver_fd; char rawline[64]; - int len; if ((ver_fd = fopen(ver_file, "r")) == NULL) { @@ -557,12 +557,8 @@ CheckDataVersion(void) exit(1); } - /* remove trailing newline, handling Windows newlines as well */ - len = strlen(rawline); - while (len > 0 && - (rawline[len - 1] == '\n' || - rawline[len - 1] == '\r')) - rawline[--len] = '\0'; + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(rawline); if (strcmp(rawline, PG_MAJORVERSION) != 0) { diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index 7e3d3f1bb2..e4093ed5af 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -15,6 +15,7 @@ #endif #include "getopt_long.h" +#include "common/string.h" #include "utils/pidfile.h" #include "pg_upgrade.h" @@ -411,7 +412,6 @@ adjust_data_dir(ClusterInfo *cluster) cmd_output[MAX_STRING]; FILE *fp, *output; - int len; /* Initially assume config dir and data dir are the same */ cluster->pgconfig = pg_strdup(cluster->pgdata); @@ -452,12 +452,8 @@ adjust_data_dir(ClusterInfo *cluster) pclose(output); - /* Remove trailing newline, handling Windows newlines as well */ - len = strlen(cmd_output); - while (len > 0 && - (cmd_output[len - 1] == '\n' || - cmd_output[len - 1] == '\r')) - cmd_output[--len] = '\0'; + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(cmd_output); cluster->pgdata = pg_strdup(cmd_output); @@ -518,15 +514,9 @@ get_sock_dir(ClusterInfo *cluster, bool live_check) sscanf(line, "%hu", &old_cluster.port); if (lineno == LOCK_FILE_LINE_SOCKET_DIR) { - int len; - + /* strip trailing newline and carriage return */ cluster->sockdir = pg_strdup(line); - /* strip off newline, handling Windows newlines as well */ - len = strlen(cluster->sockdir); - while (len > 0 && - (cluster->sockdir[len - 1] == '\n' || - cluster->sockdir[len - 1] == '\r')) - cluster->sockdir[--len] = '\0'; + (void) pg_strip_crlf(cluster->sockdir); } } fclose(fp); diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index 59afbc793a..0fcb8c7783 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -22,6 +22,7 @@ #include "prompt.h" #include "settings.h" +#include "common/string.h" /*-------------------------- * get_prompt @@ -264,7 +265,6 @@ get_prompt(promptStatus_t status, ConditionalStack cstack) FILE *fd; char *file = pg_strdup(p + 1); int cmdend; - int buflen; cmdend = strcspn(file, "`"); file[cmdend] = '\0'; @@ -275,10 +275,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack) buf[0] = '\0'; pclose(fd); } - buflen = strlen(buf); - while (buflen > 0 && (buf[buflen - 1] == '\n' || - buf[buflen - 1] == '\r')) - buf[--buflen] = '\0'; + + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(buf); + free(file); p += cmdend + 1; break; diff --git a/src/common/string.c b/src/common/string.c index b01a56ceaa..c9b8482cb0 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -90,3 +90,25 @@ pg_clean_ascii(char *str) *p = '?'; } } + + +/* + * pg_strip_crlf -- Remove any trailing newline and carriage return + * + * Removes any trailing newline and carriage return characters (\r on + * Windows) in the input string, zero-terminating it. + * + * The passed in string must be zero-terminated. This function returns + * the new length of the string. + */ +int +pg_strip_crlf(char *str) +{ + int len = strlen(str); + + while (len > 0 && (str[len - 1] == '\n' || + str[len - 1] == '\r')) + str[--len] = '\0'; + + return len; +} diff --git a/src/include/common/string.h b/src/include/common/string.h index 77f31337ca..94f653fdd7 100644 --- a/src/include/common/string.h +++ b/src/include/common/string.h @@ -14,5 +14,6 @@ extern bool pg_str_endswith(const char *str, const char *end); extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base); extern void pg_clean_ascii(char *str); +extern int pg_strip_crlf(char *str); #endif /* COMMON_STRING_H */ diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index d262b57021..fa5af18ffa 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -73,6 +73,7 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options, #include "common/ip.h" #include "common/link-canary.h" #include "common/scram-common.h" +#include "common/string.h" #include "mb/pg_wchar.h" #include "port/pg_bswap.h" @@ -6911,12 +6912,8 @@ passwordFromFile(const char *hostname, const char *port, const char *dbname, if (fgets(buf, sizeof(buf), fp) == NULL) break; - len = strlen(buf); - - /* Remove trailing newline, including \r in case we're on Windows */ - while (len > 0 && (buf[len - 1] == '\n' || - buf[len - 1] == '\r')) - buf[--len] = '\0'; + /* strip trailing newline and carriage return */ + len = pg_strip_crlf(buf); if (len == 0) continue;