Skip to content

Commit 0899d68

Browse files
authored
Merge pull request #1758 from lonvia/check-for-invalid-prefix-and-schema-names
Check more user-supplied strings used as SQL identifier
2 parents c03ea06 + 7f64c62 commit 0899d68

File tree

5 files changed

+39
-20
lines changed

5 files changed

+39
-20
lines changed

src/options.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "format.hpp"
1111
#include "logging.hpp"
1212
#include "options.hpp"
13+
#include "pgsql.hpp"
1314
#include "reprojection.hpp"
1415
#include "util.hpp"
1516
#include "version.hpp"
@@ -394,6 +395,7 @@ options_t::options_t(int argc, char *argv[]) : options_t()
394395
break;
395396
case 'p':
396397
prefix = optarg;
398+
check_identifier(prefix, "--prefix parameter");
397399
break;
398400
case 'd':
399401
database_options.db = optarg;
@@ -557,9 +559,11 @@ options_t::options_t(int argc, char *argv[]) : options_t()
557559
break;
558560
case 215:
559561
middle_dbschema = optarg;
562+
check_identifier(middle_dbschema, "--middle-schema parameter");
560563
break;
561564
case 216:
562565
output_dbschema = optarg;
566+
check_identifier(output_dbschema, "--output-pgsql-schema parameter");
563567
break;
564568
case 217:
565569
if (std::strcmp(optarg, "false") == 0) {

src/output-flex.cpp

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -983,25 +983,12 @@ int output_flex_t::app_as_geometrycollection()
983983
return 1;
984984
}
985985

986-
static void check_name(std::string const &name, char const *in)
987-
{
988-
auto const pos = name.find_first_of("\"',.;$%&/()<>{}=?^*#");
989-
990-
if (pos == std::string::npos) {
991-
return;
992-
}
993-
994-
throw std::runtime_error{
995-
"Special characters are not allowed in {} names: '{}'."_format(in,
996-
name)};
997-
}
998-
999986
flex_table_t &output_flex_t::create_flex_table()
1000987
{
1001988
std::string const table_name =
1002989
luaX_get_table_string(lua_state(), "name", -1, "The table");
1003990

1004-
check_name(table_name, "table");
991+
check_identifier(table_name, "table names");
1005992

1006993
auto const it = std::find_if(m_tables->cbegin(), m_tables->cend(),
1007994
[&table_name](flex_table_t const &table) {
@@ -1021,7 +1008,7 @@ flex_table_t &output_flex_t::create_flex_table()
10211008
lua_getfield(lua_state(), -1, "schema");
10221009
if (lua_isstring(lua_state(), -1)) {
10231010
std::string const schema = lua_tostring(lua_state(), -1);
1024-
check_name(schema, "schema");
1011+
check_identifier(schema, "schema field");
10251012
new_table.set_schema(schema);
10261013
}
10271014
lua_pop(lua_state(), 1);
@@ -1052,7 +1039,7 @@ flex_table_t &output_flex_t::create_flex_table()
10521039
lua_getfield(lua_state(), -1, "data_tablespace");
10531040
if (lua_isstring(lua_state(), -1)) {
10541041
std::string const tablespace = lua_tostring(lua_state(), -1);
1055-
check_name(tablespace, "data_tablespace");
1042+
check_identifier(tablespace, "data_tablespace field");
10561043
new_table.set_data_tablespace(tablespace);
10571044
}
10581045
lua_pop(lua_state(), 1);
@@ -1061,7 +1048,7 @@ flex_table_t &output_flex_t::create_flex_table()
10611048
lua_getfield(lua_state(), -1, "index_tablespace");
10621049
if (lua_isstring(lua_state(), -1)) {
10631050
std::string const tablespace = lua_tostring(lua_state(), -1);
1064-
check_name(tablespace, "index_tablespace");
1051+
check_identifier(tablespace, "index_tablespace field");
10651052
new_table.set_index_tablespace(tablespace);
10661053
}
10671054
lua_pop(lua_state(), 1);
@@ -1098,7 +1085,7 @@ void output_flex_t::setup_id_columns(flex_table_t *table)
10981085
if (lua_isstring(lua_state(), -1)) {
10991086
std::string const column_name =
11001087
lua_tolstring(lua_state(), -1, nullptr);
1101-
check_name(column_name, "column");
1088+
check_identifier(column_name, "column names");
11021089
auto &column = table->add_column(column_name, "id_type", "");
11031090
column.set_not_null();
11041091
} else if (!lua_isnil(lua_state(), -1)) {
@@ -1111,7 +1098,7 @@ void output_flex_t::setup_id_columns(flex_table_t *table)
11111098

11121099
std::string const name =
11131100
luaX_get_table_string(lua_state(), "id_column", -2, "The ids field");
1114-
check_name(name, "column");
1101+
check_identifier(name, "column names");
11151102

11161103
auto &column = table->add_column(name, "id_num", "");
11171104
column.set_not_null();
@@ -1143,7 +1130,7 @@ void output_flex_t::setup_flex_table_columns(flex_table_t *table)
11431130
"Column entry", "text");
11441131
char const *const name =
11451132
luaX_get_table_string(lua_state(), "column", -2, "Column entry");
1146-
check_name(name, "column");
1133+
check_identifier(name, "column names");
11471134
char const *const sql_type = luaX_get_table_string(
11481135
lua_state(), "sql_type", -3, "Column entry", "");
11491136

src/pgsql.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ std::string qualified_name(std::string const &schema, std::string const &name)
197197
return result;
198198
}
199199

200+
void check_identifier(std::string const &name, char const *in)
201+
{
202+
auto const pos = name.find_first_of("\"',.;$%&/()<>{}=?^*#");
203+
204+
if (pos == std::string::npos) {
205+
return;
206+
}
207+
208+
throw std::runtime_error{
209+
"Special characters are not allowed in {}: '{}'."_format(in, name)};
210+
}
211+
200212
std::map<std::string, std::string>
201213
get_postgresql_settings(pg_conn_t const &db_connection)
202214
{

src/pgsql.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,19 @@ std::string tablespace_clause(std::string const &name);
247247
*/
248248
std::string qualified_name(std::string const &schema, std::string const &name);
249249

250+
/**
251+
* Check that the string confirms to the identifier syntax we accept.
252+
* Throws a runtime exception if an invalid character is found.
253+
*
254+
* Note that PostgreSQL accepts any character in a quoted identifier.
255+
* This function checks for some characters that are problematic in the
256+
* internal functions that create SQL statements.
257+
*
258+
* \param name Identifier to check.
259+
* \param in Name of the identifier. Only used to create a human-readable error.
260+
*/
261+
void check_identifier(std::string const &name, char const *in);
262+
250263
struct postgis_version
251264
{
252265
int major;

src/table.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,14 @@ void table_t::start(std::string const &conninfo, std::string const &table_space)
107107

108108
//first with the regular columns
109109
for (auto const &column : m_columns) {
110+
check_identifier(column.name, "column names");
111+
check_identifier(column.type_name, "column types");
110112
sql += R"("{}" {},)"_format(column.name, column.type_name);
111113
}
112114

113115
//then with the hstore columns
114116
for (auto const &hcolumn : m_hstore_columns) {
117+
check_identifier(hcolumn, "column names");
115118
sql += R"("{}" hstore,)"_format(hcolumn);
116119
}
117120

0 commit comments

Comments
 (0)