Skip to content

Commit 4b89499

Browse files
committed
PdoPgsql::setNoticeCallback(): test with unimplemented trampoline
Add a test with a runtime BadMethodCallException. Streamline issue78621_method.phpt.
1 parent ebefdb9 commit 4b89499

File tree

3 files changed

+62
-13
lines changed

3 files changed

+62
-13
lines changed

ext/pdo_pgsql/tests/issue78621.inc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ $db->exec("insert into t values ('ah')");
1919
while (count($rounds)) {
2020
try {
2121
attach($db, array_shift($rounds));
22-
} catch (TypeError $err) {
23-
echo "Caught TypeError: ".$err->getMessage()."\n";
22+
} catch (Throwable $err) {
23+
echo "Caught ".get_class($err).": ".$err->getMessage()."\n";
24+
}
25+
try {
26+
$db->exec("delete from t");
27+
$db->exec("insert into t values ('ah')");
28+
} catch (Throwable $err) {
29+
echo "Caught ".get_class($err)." ".$err->getMessage()."\n";
2430
}
25-
$db->exec("delete from t");
26-
$db->exec("insert into t values ('ah')");
2731
}
2832
$db->setNoticeCallback(null);
2933
$db->exec("delete from t");

ext/pdo_pgsql/tests/issue78621_method.phpt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,24 @@ class Logger
1616
public function __call(string $method, array $args)
1717
{
1818
$realMethod = strtr($method, [ 'whatever' => 'disp' ]);
19+
if (!method_exists($this, $realMethod)) {
20+
throw new BadMethodCallException('Call to undefined method '.__CLASS__.'::'.$realMethod);
21+
}
1922
echo "$method trampoline for $realMethod\n";
2023
return call_user_func_array([ $this, $realMethod ], $args);
2124
}
2225
}
2326
$logger = new Logger();
24-
function attach($db, $prefix = '')
27+
function attach($db, $method)
2528
{
2629
global $logger;
27-
global $flavor;
28-
switch($flavor)
29-
{
30-
case 0: $db->setNoticeCallback([ $logger, 'disp'.$prefix ]); break;
31-
case 1: $db->setNoticeCallback([ $logger, 'whatever'.$prefix ]); break;
32-
}
30+
$db->setNoticeCallback([ $logger, $method ]);
3331
}
3432
echo "Testing with method explicitely plugged:\n";
35-
$flavor = 0;
33+
$rounds = [ 'disp', 'dispRe' ];
3634
require dirname(__FILE__) . '/issue78621.inc';
3735
echo "Testing with a bit of magic:\n";
38-
++$flavor;
36+
$rounds = [ 'whatever', 'whateverRe', 'unexisting' ];
3937
require dirname(__FILE__) . '/issue78621.inc';
4038
?>
4139
--EXPECT--
@@ -55,6 +53,7 @@ whatever trampoline for disp
5553
NOTICE: I tampered your data, did you know?
5654
whateverRe trampoline for dispRe
5755
ReNOTICE: I tampered your data, did you know?
56+
Caught BadMethodCallException Call to undefined method Logger::unexisting
5857
array(1) {
5958
[0]=>
6059
array(1) {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
PdoPgsql::setNoticeCallback() use F ZPP for trampoline callback and does not leak
3+
--EXTENSIONS--
4+
pdo
5+
pdo_pgsql
6+
--SKIPIF--
7+
<?php
8+
require __DIR__ . '/config.inc';
9+
require dirname(__DIR__, 2) . '/pdo/tests/pdo_test.inc';
10+
PDOTest::skip();
11+
?>
12+
--FILE--
13+
<?php
14+
15+
require_once __DIR__ . "/config.inc";
16+
17+
$db = new PdoPgsql($config['ENV']['PDOTEST_DSN']);
18+
19+
function disp($message) { echo trim($message)."\n"; }
20+
function attach($db, $callback) { $db->setNoticeCallback($callback); }
21+
22+
class T { public function z($m) { echo $m."\n"; } public function __call($m, $p) { echo "bah $m\n"; } }
23+
$t = new T;
24+
$rounds = [
25+
[ $t, 'disp' ],
26+
3, // Error, so the old callback is kept, and will be used in the call that follows the caught error.
27+
null, // No callback. Hopefully this clears everything.
28+
'wouldAnyoneNameAFunctionThatWay', // So this one will crash and *no output will follow*.
29+
];
30+
require __DIR__ . '/issue78621.inc';
31+
32+
?>
33+
--EXPECTF--
34+
bah disp
35+
Caught TypeError: %s: Argument #1 ($callback) %s
36+
bah disp
37+
Caught TypeError: %s: Argument #1 ($callback) %s
38+
array(1) {
39+
[0]=>
40+
array(1) {
41+
["a"]=>
42+
string(2) "oh"
43+
}
44+
}
45+
Done
46+

0 commit comments

Comments
 (0)