[pgAdmin][RM4590] Schema Backup fails with names that requires quoting

Aditya Toshniwal <[email protected]>
Newsgroups gmane.comp.db.postgresql.pgadmin.devel
Message-ID <CAM9w-_nYdZC73Tynv+QAzGtYeStsn2hEKa02B-fSxK3_EVCmCw@mail.gmail.com>
Hi Hackers,

Attached is the patch to fix the schema backup with names that requires
double quotes.
Command line has special meaning for double quotes and so the command is
run without the double quotes if applied on objects. Code is changed to add
extra pairs of quotes to save our object quotes.

Also fixed a test case which was failing if certain paths had spaces in
between.

Kindly review.

-- 
Thanks and Regards,
Aditya Toshniwal
Sr. Software Engineer | EnterpriseDB India | Pune
"Don't Complain about Heat, Plant a TREE"
RM4590.patch (application/octet-stream, 3.1 KB)
diff --git a/web/pgadmin/setup/tests/test_export_import_servers.py b/web/pgadmin/setup/tests/test_export_import_servers.py
index 564384ad..b4d6d4e3 100644
--- a/web/pgadmin/setup/tests/test_export_import_servers.py
+++ b/web/pgadmin/setup/tests/test_export_import_servers.py
@@ -36,13 +36,13 @@ class ImportExportServersTestCase(BaseTestGenerator):
 
         # Load the servers
         os.system(
-            "python %s --load-servers %s 2> %s" %
+            "python \"%s\" --load-servers \"%s\" 2> %s" %
             (setup, os.path.join(path, "servers.json"), os.devnull)
         )
 
         # And dump them again
         tf = tempfile.NamedTemporaryFile(delete=False)
-        os.system("python %s --dump-servers %s 2> %s" %
+        os.system("python \"%s\" --dump-servers \"%s\" 2> %s" %
                   (setup, tf.name, os.devnull))
 
         # Compare the JSON files, ignoring servers that exist in our
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index ac7b4ff3..b39848cb 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -269,6 +269,22 @@ def filename_with_file_manager_path(_file, create_file=True):
     return short_path
 
 
+def escape_dquotes_process_arg(arg):
+    # Double quotes has special meaning for shell command line and they are
+    # run without the double quotes. Add extra quotes to save our double
+    # quotes from stripping.
+
+    # 1st level to popen executor
+    # 2nd level actual pg_dump popen
+    levels_of_popen = 2
+    total_quotes = levels_of_popen * '"'
+
+    if not arg.startswith('"'):
+        return arg
+    else:
+        return r'{0}{1}{0}'.format(total_quotes, arg)
+
+
 @blueprint.route(
     '/job/<int:sid>', methods=['POST'], endpoint='create_server_job'
 )
@@ -419,14 +435,19 @@ def create_backup_objects_job(sid):
 
     if 'schemas' in data:
         for s in data['schemas']:
-            args.extend(['--schema', s])
+            args.extend(['--schema', r'{0}'.format(
+                driver.qtIdent(conn, s).replace('"', '\"'))])
 
     if 'tables' in data:
         for s, t in data['tables']:
             args.extend([
-                '--table', driver.qtIdent(conn, s, t)
+                '--table', r'{0}'.format(
+                    driver.qtIdent(conn, s, t).replace('"', '\"'))
             ])
 
+    escaped_args = [
+        escape_dquotes_process_arg(arg) for arg in args
+    ]
     try:
         if backup_obj_type == 'objects':
             args.append(data['database'])
@@ -439,7 +460,7 @@ def create_backup_objects_job(sid):
                     *args,
                     database=data['database']
                 ),
-                cmd=utility, args=args
+                cmd=utility, args=escaped_args
             )
         else:
             p = BatchProcess(
@@ -452,7 +473,7 @@ def create_backup_objects_job(sid):
                     ) else data['file'],
                     *args
                 ),
-                cmd=utility, args=args
+                cmd=utility, args=escaped_args
             )
 
         manager.export_password_env(p.id)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.