Skip to content

Commit bc819b5

Browse files
committed
make check_name() a global function
There are a couple of other places outside the flex output where we should check that psql identifiers are correctly quotable.
1 parent c03ea06 commit bc819b5

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

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");
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");
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");
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");
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");
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");
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");
11471134
char const *const sql_type = luaX_get_table_string(
11481135
lua_state(), "sql_type", -3, "Column entry", "");
11491136

src/pgsql.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,19 @@ 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 {} names: '{}'."_format(in,
210+
name)};
211+
}
212+
200213
std::map<std::string, std::string>
201214
get_postgresql_settings(pg_conn_t const &db_connection)
202215
{

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;

0 commit comments

Comments
 (0)