Hi Tom, b654714 has reworked the way we handle removal of CLRF for several code paths, and has repeated the same code patterns to do that in 8 different places. Could it make sense to refactor things as per the attached with a new routine in common/string.c?
Thanks, -- Michael
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 <sys/stat.h> #include <unistd.h> +#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..6ef004f192 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" @@ -2219,12 +2220,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 */ + len = 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 9d9c33d78c..702986539b 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" @@ -557,12 +558,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 */ + len = 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..c74f05c032 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -411,7 +411,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 +451,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 +513,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..7e6a1bccc3 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -90,3 +90,25 @@ pg_clean_ascii(char *str) *p = '?'; } } + + +/* + * pg_clean_crlf -- Remove any trailing newline and carriage return + * + * Removes any trailing newline and carriage return characters (\r on + * Windows), zero-terminating it. + * + * The passed in string must be zero-terminated, and 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 a329ebbf93..f824b6ab7d 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; diff --git a/src/port/sprompt.c b/src/port/sprompt.c index 02164d497a..3ecbe1f5cb 100644 --- a/src/port/sprompt.c +++ b/src/port/sprompt.c @@ -18,6 +18,7 @@ #include <termios.h> #endif +#include "common/string.h" /* * simple_prompt @@ -144,11 +145,8 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo) } while (buflen > 0 && buf[buflen - 1] != '\n'); } - /* strip trailing newline, including \r in case we're on Windows */ - while (length > 0 && - (destination[length - 1] == '\n' || - destination[length - 1] == '\r')) - destination[--length] = '\0'; + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(destination); if (!echo) {
signature.asc
Description: PGP signature