-
Notifications
You must be signed in to change notification settings - Fork 8k
ext/pgsql: route pg_copy_from table_name through build_tablename #21985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| --TEST-- | ||
| pg_copy_to() / pg_copy_from() default null marker round-trip | ||
| --EXTENSIONS-- | ||
| pgsql | ||
| --SKIPIF-- | ||
| <?php include("inc/skipif.inc"); ?> | ||
| --FILE-- | ||
| <?php | ||
|
|
||
| include('inc/config.inc'); | ||
|
|
||
| $db = pg_connect($conn_str); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_default_null'); | ||
| pg_query($db, 'CREATE TABLE pg_copy_default_null (id int, v text)'); | ||
| pg_query($db, "INSERT INTO pg_copy_default_null VALUES (1, 'hello'), (2, NULL)"); | ||
|
|
||
| $rows = pg_copy_to($db, 'pg_copy_default_null'); | ||
| var_dump($rows); | ||
|
|
||
| pg_query($db, 'DELETE FROM pg_copy_default_null'); | ||
| var_dump(pg_copy_from($db, 'pg_copy_default_null', $rows)); | ||
| var_dump(pg_fetch_all(pg_query($db, 'SELECT v FROM pg_copy_default_null ORDER BY id'))); | ||
|
|
||
| ?> | ||
| --CLEAN-- | ||
| <?php | ||
| include('inc/config.inc'); | ||
| $db = pg_connect($conn_str); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_default_null'); | ||
| ?> | ||
| --EXPECT-- | ||
| array(2) { | ||
| [0]=> | ||
| string(8) "1 hello | ||
| " | ||
| [1]=> | ||
| string(5) "2 \N | ||
| " | ||
| } | ||
| bool(true) | ||
| array(2) { | ||
| [0]=> | ||
| array(1) { | ||
| ["v"]=> | ||
| string(5) "hello" | ||
| } | ||
| [1]=> | ||
| array(1) { | ||
| ["v"]=> | ||
| NULL | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| --TEST-- | ||
| pg_copy_from() escapes the null_as argument | ||
| --EXTENSIONS-- | ||
| pgsql | ||
| --SKIPIF-- | ||
| <?php include("inc/skipif.inc"); ?> | ||
| --FILE-- | ||
| <?php | ||
|
|
||
| include('inc/config.inc'); | ||
|
|
||
| $db = pg_connect($conn_str); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_null_as_target'); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_null_as_injected'); | ||
| pg_query($db, 'CREATE TABLE pg_copy_null_as_target (v text)'); | ||
|
|
||
| $evil = "X'; CREATE TABLE pg_copy_null_as_injected (v text); --"; | ||
| var_dump(pg_copy_from($db, 'pg_copy_null_as_target', ["row\n"], "\t", $evil)); | ||
|
|
||
| $r = pg_query($db, "SELECT 1 FROM pg_tables WHERE tablename = 'pg_copy_null_as_injected'"); | ||
| var_dump(pg_num_rows($r)); | ||
|
|
||
| $r = pg_query($db, 'SELECT v FROM pg_copy_null_as_target ORDER BY v'); | ||
| var_dump(pg_fetch_all($r)); | ||
|
|
||
| ?> | ||
| --CLEAN-- | ||
| <?php | ||
| include('inc/config.inc'); | ||
| $db = pg_connect($conn_str); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_null_as_target'); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_null_as_injected'); | ||
| ?> | ||
| --EXPECT-- | ||
| bool(true) | ||
| int(0) | ||
| array(1) { | ||
| [0]=> | ||
| array(1) { | ||
| ["v"]=> | ||
| string(3) "row" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| --TEST-- | ||
| pg_copy_from() escapes the table name argument | ||
| --EXTENSIONS-- | ||
| pgsql | ||
| --SKIPIF-- | ||
| <?php include("inc/skipif.inc"); ?> | ||
| --FILE-- | ||
| <?php | ||
|
|
||
| include('inc/config.inc'); | ||
|
|
||
| $db = pg_connect($conn_str); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_from_target'); | ||
| pg_query($db, 'CREATE TABLE pg_copy_from_target (v text)'); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_from_other'); | ||
| pg_query($db, 'CREATE TABLE pg_copy_from_other (v text)'); | ||
|
|
||
| $evil = "pg_copy_from_other FROM STDIN --"; | ||
| var_dump(pg_copy_from($db, $evil, ["redirected\n"])); | ||
|
|
||
| $rows = pg_fetch_all(pg_query($db, 'SELECT v FROM pg_copy_from_other')) ?: []; | ||
| var_dump($rows); | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add a case that tries to close the wrapper early, like '(SELECT 1)); DROP TABLE pg_copy_to_qsource; --', plus the pg_tables check?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the wrapper-close test case plus a paren-balance check on the (query) input: must start with |
||
| ?> | ||
| --CLEAN-- | ||
| <?php | ||
| include('inc/config.inc'); | ||
| $db = pg_connect($conn_str); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_from_target'); | ||
| pg_query($db, 'DROP TABLE IF EXISTS pg_copy_from_other'); | ||
| ?> | ||
| --EXPECTF-- | ||
| Warning: pg_copy_from(): Invalid table_name 'pg_copy_from_other FROM STDIN --': must be a plain identifier or schema.table in %s on line %d | ||
| bool(false) | ||
| array(0) { | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same gate applied here.