php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #78621 pgsqlSetNoticeCallback
Submitted: 2019-10-02 05:04 UTC Modified: -
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: guillaume-php at outters dot eu Assigned:
Status: Open Package: PDO PgSQL
PHP Version: 7.3.10 OS: all
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
41 + 20 = ?
Subscribe to this entry?

 
 [2019-10-02 05:04 UTC] guillaume-php at outters dot eu
Description:
------------
There is currently no way to receive PostgreSQL's notices PHP-side.

A PQsetNoticeProcessor has been defined 15 years ago to the empty function _pdo_pgsql_notice, to prevent libpq's default behaviour (fprintfing to stderr)).

Passing notices to PHP could prove useful, allowing e.g. user-defined RAISE NOTICE in PL/pgSQL long-running code to provide feedback.

A user-space callback would give more control on what to do with the message (compared to the exec-then-fetch method of non-PDO pgsql driver's pg_last_notice)… not the least being the live feedback ability.

Test script:
---------------
function disp($message) { echo trim($message)."\n"; }
$db = new PDO('pgsql:host=localhost;port=5432;dbname=…', '', '');
if(method_exists($db, 'pgsqlSetNoticeCallback'))
    $db->pgsqlSetNoticeCallback('disp');
$db->beginTransaction();
$db->exec("create temporary table t (a varchar(3))");
$db->exec("create function hey() returns trigger as \$\$ begin new.a := 'oh'; raise notice 'I tampered your data, did you know?'; return new; end; \$\$ language plpgsql");
$db->exec("create trigger hop before insert on t for each row execute procedure hey()");
$db->exec("insert into t values ('ah')");
print_r($db->query("select * from t")->fetchAll());

Expected result:
----------------
I would like to know that a trigger triggered ("I tampered your data, did you know?").

Actual result:
--------------
Only tcpdump will display my carefully-crafted RAISE NOTICE. 

Patches

pgsqlSetNoticeCallback.8.diff (last revision 2021-03-11 17:35 UTC by guillaume-php at outters dot eu)
pgsqlSetNoticeCallback.7.diff (last revision 2019-10-02 05:05 UTC by guillaume-php at outters dot eu)

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-02 05:05 UTC] guillaume-php at outters dot eu
The following patch has been added/updated:

Patch Name: pgsqlSetNoticeCallback.7.diff
Revision:   1569992718
URL:        https://bugs.php.net/patch-display.php?bug=78621&patch=pgsqlSetNoticeCallback.7.diff&revision=1569992718
 [2019-10-13 23:17 UTC] guillaume-php at outters dot eu
The following pull request has been associated:

Patch Name: pgsqlSetNoticeCallback
On GitHub:  https://github.com/php/php-src/pull/4823
Patch:      https://github.com/php/php-src/pull/4823.patch
 [2019-12-04 06:21 UTC] guillaume-php at outters dot eu
Note: I considered adding the PDO itself as a first parameter to the callback.

I don't see a usage for it now *; but who knows… Not me, but I would be open to anyone commenting this point of design: now would be the right time to add a first parameter if you think it could be a good idea (with the usual warnings in the user doc: "you get the parameter, but don't dare doing nasty things with it, you'll be on your own to deal with it").

If no comment, I'll stick with the simple, user-side solution exposed here, that is, to get a calling context, do pass an object method to pgsqlSetNoticeCallback and hold your context in that object.

* Conjecture: someone needing to act on the statement upon receiving a notice, e.g. aborting it?
Objection: wouldn't it raise reentrancy issues? And by the way, what is the "current" statement when we have two, not entirely fetched statements? I'm not even sure we can retrieve it from the notice (the notice being emitted at the connection level, not at the statement level).
Conjecture: use it as a discriminant in the callback to know for which DB we get the notice?
Objection: the callback can be an object method, and the object can hold the calling context.
Conjecture: to be consistent with notice callbacks on other drivers?
Objection: I did not see any other implementation…
 [2021-03-11 17:35 UTC] guillaume-php at outters dot eu
The following patch has been added/updated:

Patch Name: pgsqlSetNoticeCallback.8.diff
Revision:   1615484135
URL:        https://bugs.php.net/patch-display.php?bug=78621&patch=pgsqlSetNoticeCallback.8.diff&revision=1615484135
 [2021-03-11 23:24 UTC] guillaume-php at outters dot eu
The following pull request has been associated:

Patch Name: pgsqlSetNoticeCallback
On GitHub:  https://github.com/php/php-src/pull/6764
Patch:      https://github.com/php/php-src/pull/6764.patch
 [2023-02-02 06:07 UTC] test at gmail dot com
hey testing comment for xss

<h1>hello team</h1>
"><img%20src=a%20onerror=alert(document.domain)>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 06:01:29 2024 UTC