[glom] Escape database connection details properly.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Escape database connection details properly.
- Date: Thu, 10 Nov 2011 09:23:08 +0000 (UTC)
commit 6d313884cbd31d6f035ae71254c2858a9a82f02e
Author: Murray Cumming <murrayc murrayc com>
Date: Thu Nov 10 10:22:55 2011 +0100
Escape database connection details properly.
* glom/libglom/db_utils.[h|cc]: Added gda_cnc_string_encode() for use
with GdaConnection's cnc_string and auth_string, for instance to
escape the database directory, name, username, and password.
* glom/libglom/connectionpool_backends/postgres.cc:
* glom/libglom/connectionpool_backends/postgres_self.cc:
* glom/libglom/connectionpool_backends/sqlite.cc: Properly escape the
cnc_string and auth_string key values.
* tests/test_selfhosting_utils.cc: test_create_and_selfhost_from_example(),
test_create_and_selfhost_from_uri(): Add an optional subdirectory parameter
that we can use to force weird parts into the path.
* Makefile_tests.am:
* tests/test_selfhosting_new_from_example_strangepath.cc: Add a
test case that uses a path with some weird characters. This now works
thanks to the above changes.
ChangeLog | 20 +++++
Makefile_tests.am | 7 ++
glom/libglom/connectionpool_backends/postgres.cc | 10 ++-
.../connectionpool_backends/postgres_self.cc | 1 +
glom/libglom/connectionpool_backends/sqlite.cc | 10 ++-
glom/libglom/db_utils.cc | 9 ++
glom/libglom/db_utils.h | 5 +
...est_selfhosting_new_from_example_strangepath.cc | 83 ++++++++++++++++++++
tests/test_selfhosting_utils.cc | 10 ++-
tests/test_selfhosting_utils.h | 6 +-
10 files changed, 148 insertions(+), 13 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e9fddc3..85e9166 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2011-11-10 Murray Cumming <murrayc murrayc com>
+
+ Escape database connection details properly.
+
+ * glom/libglom/db_utils.[h|cc]: Added gda_cnc_string_encode() for use
+ with GdaConnection's cnc_string and auth_string, for instance to
+ escape the database directory, name, username, and password.
+ * glom/libglom/connectionpool_backends/postgres.cc:
+ * glom/libglom/connectionpool_backends/postgres_self.cc:
+ * glom/libglom/connectionpool_backends/sqlite.cc: Properly escape the
+ cnc_string and auth_string key values.
+
+ * tests/test_selfhosting_utils.cc: test_create_and_selfhost_from_example(),
+ test_create_and_selfhost_from_uri(): Add an optional subdirectory parameter
+ that we can use to force weird parts into the path.
+ * Makefile_tests.am:
+ * tests/test_selfhosting_new_from_example_strangepath.cc: Add a
+ test case that uses a path with some weird characters. This now works
+ thanks to the above changes.
+
2011-11-09 Murray Cumming <murrayc murrayc com>
Use Glib::shell_quote() when spawning tar.
diff --git a/Makefile_tests.am b/Makefile_tests.am
index a554577..74f333f 100644
--- a/Makefile_tests.am
+++ b/Makefile_tests.am
@@ -27,6 +27,7 @@ check_PROGRAMS = \
tests/python/test_python_module \
tests/test_selfhosting_new_empty \
tests/test_selfhosting_new_from_example \
+ tests/test_selfhosting_new_from_example_strangepath \
tests/test_selfhosting_new_then_report \
tests/test_selfhosting_new_then_image \
tests/test_selfhosting_new_then_backup_restore \
@@ -48,6 +49,7 @@ TESTS = tests/test_document_load \
tests/python/test_python_module \
tests/test_selfhosting_new_empty \
tests/test_selfhosting_new_from_example \
+ tests/test_selfhosting_new_from_example_strangepath \
tests/test_selfhosting_new_then_report \
tests/test_selfhosting_new_then_backup_restore \
tests/test_selfhosting_new_then_image \
@@ -148,6 +150,11 @@ tests_test_selfhosting_new_from_example_SOURCES = tests/test_selfhosting_new_fro
tests_test_selfhosting_new_from_example_LDADD = $(tests_ldadd)
tests_test_selfhosting_new_from_example_CPPFLAGS = $(tests_cppflags)
+
+tests_test_selfhosting_new_from_example_strangepath_SOURCES = tests/test_selfhosting_new_from_example_strangepath.cc $(sources_test_selfhosting_utils)
+tests_test_selfhosting_new_from_example_strangepath_LDADD = $(tests_ldadd)
+tests_test_selfhosting_new_from_example_strangepath_CPPFLAGS = $(tests_cppflags)
+
tests_test_selfhosting_new_then_report_SOURCES = tests/test_selfhosting_new_then_report.cc $(sources_test_selfhosting_utils)
tests_test_selfhosting_new_then_report_LDADD = $(tests_ldadd)
tests_test_selfhosting_new_then_report_CPPFLAGS = $(tests_cppflags)
diff --git a/glom/libglom/connectionpool_backends/postgres.cc b/glom/libglom/connectionpool_backends/postgres.cc
index 3b6546f..df2e582 100644
--- a/glom/libglom/connectionpool_backends/postgres.cc
+++ b/glom/libglom/connectionpool_backends/postgres.cc
@@ -46,7 +46,8 @@ static Glib::ustring create_auth_string(const Glib::ustring& username, const Gli
if(username.empty() and password.empty())
return Glib::ustring();
else
- return "USERNAME=" + username + ";PASSWORD=" + password; //TODO: How should we quote and escape these?
+ return "USERNAME=" + Glom::DbUtils::gda_cnc_string_encode(username) +
+ ";PASSWORD=" + Glom::DbUtils::gda_cnc_string_encode(password);
}
} //anonymous namespace
@@ -69,8 +70,9 @@ Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustri
//This _might_ be different on some systems. I hope not. murrayc
const Glib::ustring default_database = "template1";
//const Glib::ustring& actual_database = (!database.empty()) ? database : default_database;;
- const Glib::ustring cnc_string_main = "HOST=" + m_host + ";PORT=" + port;
- Glib::ustring cnc_string = cnc_string_main + ";DB_NAME=" + database;
+ const Glib::ustring cnc_string_main = "HOST=" + DbUtils::gda_cnc_string_encode(m_host)
+ + ";PORT=" + DbUtils::gda_cnc_string_encode(port);
+ const Glib::ustring cnc_string = cnc_string_main + ";DB_NAME=" + DbUtils::gda_cnc_string_encode(database);
Glib::RefPtr<Gnome::Gda::Connection> connection;
Glib::RefPtr<Gnome::Gda::DataModel> data_model;
@@ -99,7 +101,7 @@ Glib::RefPtr<Gnome::Gda::Connection> Postgres::attempt_connect(const Glib::ustri
std::cout << "debug: " << G_STRFUNC << ": Attempting to connect without specifying the database." << std::endl;
#endif
- const Glib::ustring cnc_string = cnc_string_main + ";DB_NAME=" + default_database;
+ const Glib::ustring cnc_string = cnc_string_main + ";DB_NAME=" + DbUtils::gda_cnc_string_encode(default_database);
Glib::RefPtr<Gnome::Gda::Connection> temp_conn;
Glib::ustring auth_string = create_auth_string(username, password);
try
diff --git a/glom/libglom/connectionpool_backends/postgres_self.cc b/glom/libglom/connectionpool_backends/postgres_self.cc
index c77e12d..1ba19ba 100644
--- a/glom/libglom/connectionpool_backends/postgres_self.cc
+++ b/glom/libglom/connectionpool_backends/postgres_self.cc
@@ -435,6 +435,7 @@ Backend::StartupErrors PostgresSelfHosted::startup(const SlotProgress& slot_prog
+ " -c ident_file=" + Glib::shell_quote(dbdir_ident)
+ " -k " + Glib::shell_quote(dbdir)
+ " --external_pid_file=" + Glib::shell_quote(dbdir_pid);
+ //std::cout << G_STRFUNC << ": debug: " << command_postgres_start << std::endl;
// Make sure to use double quotes for the executable path, because the
// CreateProcess() API used on Windows does not support single quotes.
diff --git a/glom/libglom/connectionpool_backends/sqlite.cc b/glom/libglom/connectionpool_backends/sqlite.cc
index fa4eff1..1af915f 100644
--- a/glom/libglom/connectionpool_backends/sqlite.cc
+++ b/glom/libglom/connectionpool_backends/sqlite.cc
@@ -53,6 +53,7 @@ Glib::RefPtr<Gnome::Gda::Connection> Sqlite::connect(const Glib::ustring& databa
if(!file_exists)
{
std::cerr << G_STRFUNC << ": The db file does not exist at path: " << db_file->get_uri() << std::endl;
+ //std::cerr << " as filepath: " << db_file->get_path() << std::endl;
}
else
{
@@ -65,8 +66,10 @@ Glib::RefPtr<Gnome::Gda::Connection> Sqlite::connect(const Glib::ustring& databa
// Convert URI to path, for GDA connection string
const std::string database_directory = db_dir->get_path();
- const Glib::ustring cnc_string = "DB_DIR=" + database_directory + ";DB_NAME=" + database;
- const Glib::ustring auth_string = Glib::ustring::compose("USERNAME=%1;PASSWORD=%2", username, password);
+ const Glib::ustring cnc_string = "DB_DIR=" + DbUtils::gda_cnc_string_encode(database_directory) +
+ ";DB_NAME=" + DbUtils::gda_cnc_string_encode(database);
+ const Glib::ustring auth_string = Glib::ustring::compose("USERNAME=%1;PASSWORD=%2",
+ DbUtils::gda_cnc_string_encode(username), DbUtils::gda_cnc_string_encode(password));
connection = Gnome::Gda::Connection::open_from_string("SQLite",
cnc_string, auth_string,
@@ -100,7 +103,8 @@ bool Sqlite::create_database(const Glib::ustring& database_name, const Glib::ust
Glib::RefPtr<Gio::File> file = Gio::File::create_for_uri(m_database_directory_uri);
const std::string database_directory = file->get_path();
- const Glib::ustring cnc_string = Glib::ustring::compose("DB_DIR=%1;DB_NAME=%2", database_directory, database_name);
+ const Glib::ustring cnc_string = Glib::ustring::compose("DB_DIR=%1;DB_NAME=%2",
+ DbUtils::gda_cnc_string_encode(database_directory), DbUtils::gda_cnc_string_encode(database_name));
Glib::RefPtr<Gnome::Gda::Connection> cnc =
Gnome::Gda::Connection::open_from_string("SQLite",
diff --git a/glom/libglom/db_utils.cc b/glom/libglom/db_utils.cc
index 0765fdf..704f768 100644
--- a/glom/libglom/db_utils.cc
+++ b/glom/libglom/db_utils.cc
@@ -1871,6 +1871,15 @@ Glib::ustring escape_sql_id(const Glib::ustring& id)
return gda_connection->quote_sql_identifier(id);
}
+Glib::ustring gda_cnc_string_encode(const Glib::ustring& str)
+{
+ char* pch = gda_rfc1738_encode(str.c_str());
+ if(!pch)
+ return Glib::ustring();
+ else
+ return Glib::ustring(pch);
+}
+
Glib::ustring build_query_create_group(const Glib::ustring& group, bool superuser)
{
if(group.empty())
diff --git a/glom/libglom/db_utils.h b/glom/libglom/db_utils.h
index 513cd89..a50df37 100644
--- a/glom/libglom/db_utils.h
+++ b/glom/libglom/db_utils.h
@@ -151,6 +151,11 @@ bool drop_table(const Glib::ustring& table_name);
*/
Glib::ustring escape_sql_id(const Glib::ustring& id);
+/** Just a wrapper around gda_rfc1738_encode(),
+ * for use when building libgda connection strings or authentication strings.
+ */
+Glib::ustring gda_cnc_string_encode(const Glib::ustring& str);
+
Glib::ustring build_query_create_group(const Glib::ustring& group, bool superuser = false);
Glib::ustring build_query_add_user_to_group(const Glib::ustring& group, const Glib::ustring& user);
diff --git a/tests/test_selfhosting_new_from_example_strangepath.cc b/tests/test_selfhosting_new_from_example_strangepath.cc
new file mode 100644
index 0000000..c074cbd
--- /dev/null
+++ b/tests/test_selfhosting_new_from_example_strangepath.cc
@@ -0,0 +1,83 @@
+/* Glom
+ *
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+71 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "tests/test_selfhosting_utils.h"
+#include <libglom/init.h>
+#include <libglom/utils.h>
+#include <libglom/db_utils.h>
+#include <glib.h> //For g_assert()
+#include <iostream>
+#include <cstdlib> //For EXIT_SUCCESS and EXIT_FAILURE
+
+static bool test(Glom::Document::HostingMode hosting_mode)
+{
+ Glom::Document document;
+ const bool recreated =
+ test_create_and_selfhost_from_example("example_music_collection.glom", document,
+ hosting_mode, "path with space and \" quote and single ' quote and $ dollar sign and / forward slash and \backwards slash ");
+ if(!recreated)
+ {
+ std::cerr << "Recreation failed." << std::endl;
+ return false;
+ }
+
+ if(!test_example_musiccollection_data(&document))
+ {
+ std::cerr << "test_example_musiccollection_data() failed." << std::endl;
+ return false;
+ }
+
+ if(!test_table_exists("songs", document))
+ {
+ return false;
+ }
+
+ if(!test_table_exists("publishers", document))
+ {
+ return false;
+ }
+
+ test_selfhosting_cleanup();
+
+ return true;
+}
+
+int main()
+{
+ Glom::libglom_init();
+
+ if(!test(Glom::Document::HOSTING_MODE_POSTGRES_SELF))
+ {
+ std::cerr << "Failed with PostgreSQL" << std::endl;
+ test_selfhosting_cleanup();
+ return EXIT_FAILURE;
+ }
+
+ if(!test(Glom::Document::HOSTING_MODE_SQLITE))
+ {
+ std::cerr << "Failed with SQLite" << std::endl;
+ test_selfhosting_cleanup();
+ return EXIT_FAILURE;
+ }
+
+ Glom::libglom_deinit();
+
+ return EXIT_SUCCESS;
+}
diff --git a/tests/test_selfhosting_utils.cc b/tests/test_selfhosting_utils.cc
index f65d550..16493c8 100644
--- a/tests/test_selfhosting_utils.cc
+++ b/tests/test_selfhosting_utils.cc
@@ -138,7 +138,7 @@ void test_selfhosting_cleanup()
temp_filepath_dir.clear();
}
-bool test_create_and_selfhost_from_example(const std::string& example_filename, Glom::Document& document, Glom::Document::HostingMode hosting_mode)
+bool test_create_and_selfhost_from_example(const std::string& example_filename, Glom::Document& document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path)
{
Glib::ustring uri;
@@ -156,10 +156,10 @@ bool test_create_and_selfhost_from_example(const std::string& example_filename,
return false;
}
- return test_create_and_selfhost_from_uri(uri, document, hosting_mode);
+ return test_create_and_selfhost_from_uri(uri, document, hosting_mode, subdirectory_path);
}
-bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Glom::Document& document, Glom::Document::HostingMode hosting_mode)
+bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Glom::Document& document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path)
{
if( (hosting_mode != Glom::Document::HOSTING_MODE_POSTGRES_SELF) &&
(hosting_mode != Glom::Document::HOSTING_MODE_SQLITE) )
@@ -189,10 +189,12 @@ bool test_create_and_selfhost_from_uri(const Glib::ustring& example_file_uri, Gl
Glom::ConnectionPool* connection_pool = Glom::ConnectionPool::get_instance();
//Save a copy, specifying the path to file in a directory:
- //For instance, /tmp/testfileglom/testfile.glom");
+ //For instance, /tmp/testglom/testglom.glom");
const std::string temp_filename = "testglom";
temp_filepath_dir =
Glom::Utils::get_temp_directory_path(temp_filename);
+ if(!subdirectory_path.empty())
+ temp_filepath_dir = Glib::build_filename(temp_filepath_dir, subdirectory_path);
const std::string temp_filepath = Glib::build_filename(temp_filepath_dir, temp_filename);
//Make sure that the file does not exist yet:
diff --git a/tests/test_selfhosting_utils.h b/tests/test_selfhosting_utils.h
index d442cbf..355054f 100644
--- a/tests/test_selfhosting_utils.h
+++ b/tests/test_selfhosting_utils.h
@@ -28,14 +28,16 @@
/** Create a .glom file from an example, with database data, and start a PostgreSQL server if necessary.
*
* @param hosting_mode Either HOSTING_MODE_POSTGRES_SELF or HOSTING_MODE_SQLITE
+ * @param subdirectory_path: An additional directory path to use under the temporary directory that will be used to save the file.
*/
-bool test_create_and_selfhost_from_example(const std::string& example_filename, Glom::Document& document, Glom::Document::HostingMode hosting_mode);
+bool test_create_and_selfhost_from_example(const std::string& example_filename, Glom::Document& document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string());
/** Create a .glom file from an existing .glom example file with database data, and start a PostgreSQL server if necessary.
*
* @param hosting_mode Either HOSTING_MODE_POSTGRES_SELF or HOSTING_MODE_SQLITE
+ * @param subdirectory_path: An additional directory path to use under the temporary directory that will be used to save the file.
*/
-bool test_create_and_selfhost_from_uri(const Glib::ustring& file_uri, Glom::Document& document, Glom::Document::HostingMode hosting_mode);
+bool test_create_and_selfhost_from_uri(const Glib::ustring& file_uri, Glom::Document& document, Glom::Document::HostingMode hosting_mode, const std::string& subdirectory_path = std::string());
bool test_model_expected_size(const Glib::RefPtr<Gnome::Gda::DataModel>& data_model, guint columns_count, guint rows_count);
bool test_table_exists(const Glib::ustring& table_name, const Glom::Document& document);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]