Fix potential infinite loop in CDB_QueryStatements

This fix was already present at one point in cartodb/lib/sql
(where the code was copied from) but in a different branch than
the one the code was initially copied from.

The fix depends on plpython language which becomes a new dependency.
This commit is contained in:
Sandro Santilli
2014-06-05 15:00:57 +02:00
parent fba8d3ab84
commit f9f73d2d62
8 changed files with 64 additions and 10 deletions

5
NEWS
View File

@@ -1,6 +1,10 @@
0.2.0dev - 2014-MM-DD
------------------
Important changes:
- This release adds dependency on "plpythonu" extension
Bug fixes:
- Fix recursive trigger on create table (#32)
@@ -8,6 +12,7 @@ Bug fixes:
- Fully qualify call to cdb_disable_ddl_hooks from cdb_enable_ddl_hooks
- Fully qualify call to CDB_UserDataSize from quota trigger
- Fix potential infinite loop in CDB_CartodbfyTable
- Fix potential infinite loop in CDB_QueryStatements
Enhancements:

View File

@@ -11,7 +11,8 @@ See https://github.com/CartoDB/cartodb/wiki/CartoDB-PostgreSQL-extension
Dependencies
------------
* PostgreSQL 9.3+
* PostgreSQL 9.3+ (with plpythonu extension)
* [PostGIS extension](http://postgis.net)
* [Schema triggers extension]
(https://bitbucket.org/malloclabs/pg_schema_triggers)
(or [fork](https://github.com/CartoDB/pg_schema_triggers))

View File

@@ -3,4 +3,4 @@ comment = 'Turn a database into a cartodb user database.'
superuser = true
relocatable = false
schema = cartodb
requires = 'schema_triggers, postgis'
requires = 'schema_triggers, postgis, plpythonu'

View File

@@ -1,5 +1,6 @@
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION plpythonu;
CREATE EXTENSION cartodb;
CREATE FUNCTION public.cdb_invalidate_varnish(table_name text)
RETURNS void AS $$

View File

@@ -1,13 +1,14 @@
-- Return an array of statements found in the given query text
--
-- Curtesy of Hubert Lubaczewski (depesz)
-- Regexp curtesy of Hubert Lubaczewski (depesz)
-- Implemented in plpython for performance reasons
--
CREATE OR REPLACE FUNCTION CDB_QueryStatements(query text)
RETURNS SETOF TEXT AS $$
SELECT stmt FROM (
SELECT btrim(q[1], E' \n\t\r;') as stmt FROM (
SELECT regexp_matches( $1, $REG$((?:[^'"$;]+|"[^"]*"|'(?:[^']*|'')*'|(\$[^$]*\$).*?\2)+)$REG$, 'g' ) as q
) i
) j
WHERE stmt <> '';
$$ language sql IMMUTABLE STRICT;
import re
pat = re.compile( r'''((?:[^'"$;]+|"[^"]*"|'[^']*'|(\$[^$]*\$).*?\2)+)''', re.DOTALL )
for match in pat.findall(query):
cleaned = match[0].strip()
if ( cleaned ):
yield cleaned
$$ language 'plpythonu' IMMUTABLE STRICT;

View File

@@ -1,5 +1,6 @@
CREATE EXTENSION postgis;
CREATE EXTENSION schema_triggers;
CREATE EXTENSION plpythonu;
CREATE EXTENSION cartodb;
CREATE FUNCTION public.cdb_invalidate_varnish(table_name text)
RETURNS void AS $$

View File

@@ -26,3 +26,38 @@ INSER INTO "my''""t" values ('''','""'';;');
SELECT $qu;oted$ hi $qu;oted$;
$the_param$) as statement )
SELECT '5', row_number() over (), statement FROM q;
WITH q AS ( SELECT CDB_QueryStatements($the_param$
SELECT
1 ; SELECT
2
$the_param$) as statement )
SELECT '6', row_number() over (), statement FROM q;
-- This is an insane input, illegal sql
-- we are really only testing that it does not
-- take forever to process..
-- The actual result is not correct, so if the function
-- ever gets fixed check if it's better
WITH q AS ( SELECT CDB_QueryStatements($the_param$
/a
$b$
$c$d
;
$the_param$) as statement )
SELECT '7', row_number() over (), statement FROM q;
WITH q AS ( SELECT CDB_QueryStatements($the_param$
SELECT $quoted$ hi
$quoted$;
$the_param$) as statement )
SELECT '8', row_number() over (), statement FROM q;

View File

@@ -7,3 +7,13 @@
4|4|SELECT 5
5|1|INSER INTO "my''""t" values ('''','""'';;')
5|2|SELECT $qu;oted$ hi $qu;oted$
6|1|SELECT
1
6|2|SELECT
2
7|1|/a
7|2|b
7|3|c
7|4|d
8|1|SELECT $quoted$ hi
$quoted$