createdb: Fix quoting of --encoding, --lc-ctype and --lc-collate
authorMichael Paquier <michael@paquier.xyz>
Thu, 27 Feb 2020 02:20:46 +0000 (11:20 +0900)
committerMichael Paquier <michael@paquier.xyz>
Thu, 27 Feb 2020 02:20:46 +0000 (11:20 +0900)
The original coding failed to properly quote those arguments, leading to
failures when using quotes in the values used.  As the quoting can be
encoding-sensitive, the connection to the backend needs to be taken
before applying the correct quoting.

Author: Michael Paquier
Reviewed-by: Daniel Gustafsson
Discussion: https://postgr.es/m/20200214041004.GB1998@paquier.xyz
Backpatch-through: 9.5

src/bin/scripts/createdb.c
src/bin/scripts/t/020_createdb.pl

index 68de2078e939f7454532e074d8f5e4906c08f2ad..4733af8e97ba28f8faf3966134bd31d644f1e998 100644 (file)
@@ -176,6 +176,13 @@ main(int argc, char *argv[])
                        dbname = get_user_name_or_exit(progname);
        }
 
+       /* No point in trying to use postgres db when creating postgres db. */
+       if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
+               maintenance_db = "template1";
+
+       conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
+                                                                         prompt_password, progname, echo);
+
        initPQExpBuffer(&sql);
 
        appendPQExpBuffer(&sql, "CREATE DATABASE %s",
@@ -186,23 +193,25 @@ main(int argc, char *argv[])
        if (tablespace)
                appendPQExpBuffer(&sql, " TABLESPACE %s", fmtId(tablespace));
        if (encoding)
-               appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
+       {
+               appendPQExpBufferStr(&sql, " ENCODING ");
+               appendStringLiteralConn(&sql, encoding, conn);
+       }
        if (template)
                appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
        if (lc_collate)
-               appendPQExpBuffer(&sql, " LC_COLLATE '%s'", lc_collate);
+       {
+               appendPQExpBufferStr(&sql, " LC_COLLATE ");
+               appendStringLiteralConn(&sql, lc_collate, conn);
+       }
        if (lc_ctype)
-               appendPQExpBuffer(&sql, " LC_CTYPE '%s'", lc_ctype);
+       {
+               appendPQExpBufferStr(&sql, " LC_CTYPE ");
+               appendStringLiteralConn(&sql, lc_ctype, conn);
+       }
 
        appendPQExpBufferChar(&sql, ';');
 
-       /* No point in trying to use postgres db when creating postgres db. */
-       if (maintenance_db == NULL && strcmp(dbname, "postgres") == 0)
-               maintenance_db = "template1";
-
-       conn = connectMaintenanceDatabase(maintenance_db, host, port, username,
-                                                                         prompt_password, progname, echo);
-
        if (echo)
                printf("%s\n", sql.data);
        result = PQexec(conn, sql.data);
index c0f6067a923e9f4a10730bff4eae2ea9d3fb8e27..d94d4edd901fad8d12dda61871e6f9a0e5d557f9 100644 (file)
@@ -3,7 +3,7 @@ use warnings;
 
 use PostgresNode;
 use TestLib;
-use Test::More tests => 13;
+use Test::More tests => 22;
 
 program_help_ok('createdb');
 program_version_ok('createdb');
@@ -24,3 +24,27 @@ $node->issues_sql_like(
 
 $node->command_fails([ 'createdb', 'foobar1' ],
        'fails if database already exists');
+
+# Check quote handling with incorrect option values.
+$node->command_checks_all(
+       [ 'createdb', '--encoding', "foo'; SELECT '1", 'foobar2' ],
+       1,
+       [qr/^$/],
+       [qr/^createdb: error: "foo'; SELECT '1" is not a valid encoding name/s],
+       'createdb with incorrect --lc-collate');
+$node->command_checks_all(
+       [ 'createdb', '--lc-collate', "foo'; SELECT '1", 'foobar2' ],
+       1,
+       [qr/^$/],
+       [
+               qr/^createdb: error: database creation failed: ERROR:  invalid locale name/s
+       ],
+       'createdb with incorrect --lc-collate');
+$node->command_checks_all(
+       [ 'createdb', '--lc-ctype', "foo'; SELECT '1", 'foobar2' ],
+       1,
+       [qr/^$/],
+       [
+               qr/^createdb: error: database creation failed: ERROR:  invalid locale name/s
+       ],
+       'createdb with incorrect --lc-ctype');