Refactor logic to remove trailing CR/LF characters from strings
authorMichael Paquier <michael@paquier.xyz>
Fri, 9 Aug 2019 02:05:14 +0000 (11:05 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 9 Aug 2019 02:05:14 +0000 (11:05 +0900)
b654714 has reworked the way trailing CR/LF characters are removed from
strings.  This commit introduces a new routine in common/string.c and
refactors the code so as the logic is in a single place, mostly.

Author: Michael Paquier
Reviewed-by: Bruce Momjian
Discussion: https://postgr.es/m/20190801031820.GF29334@paquier.xyz

src/backend/libpq/be-secure-common.c
src/bin/pg_ctl/pg_ctl.c
src/bin/pg_resetwal/pg_resetwal.c
src/bin/pg_upgrade/option.c
src/bin/psql/prompt.c
src/common/string.c
src/include/common/string.h
src/interfaces/libpq/fe-connect.c

index 4abbef5bf1907fe13b0e51cd2f4c6137d1da6c75..e8f27bc78257b2b1e0714995d8e6d0b86b38da96 100644 (file)
@@ -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);
index 068b65a2af765b75420efcf6c09470f7d908b8b2..dd76be6dd2eda6e7a2d37da425ee79fefb330189 100644 (file)
@@ -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);
index 74063ebf2f97205475d87b6a13111097bab26a53..159a30b520a2e1f5a3e1cea2c961e143e2df1392 100644 (file)
@@ -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)
    {
index 7e3d3f1bb27586992c92623baaf37d9bff3787e9..e4093ed5afc204b7d9e5ad33e76314a526a37c89 100644 (file)
@@ -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);
index 59afbc793a9927006d894eb025b99d8fae959338..0fcb8c7783210894b1a5a2ebaffc2041be3810fe 100644 (file)
@@ -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;
index b01a56ceaa54d7491668a11225df45d23b4a1aed..c9b8482cb060351cfbf6c4e9a48f5cc5e64e2b01 100644 (file)
@@ -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;
+}
index 77f31337ca43ea7e3986dce2a3a119d9b9a9a942..94f653fdd75ca2bf03485a9a652d9c313b12a553 100644 (file)
@@ -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 */
index d262b57021d9ee39ee1af63500ae96483c71165e..fa5af18ffac030be0e5ef2aec1e81a6a3f998b66 100644 (file)
@@ -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;