1--TEST--
2SQLite3 user authorizer callback
3--SKIPIF--
4<?php require_once(__DIR__ . '/skipif.inc'); ?>
5--FILE--
6<?php
7
8$db = new SQLite3(':memory:');
9$db->enableExceptions(true);
10
11$db->setAuthorizer(function (int $action) {
12    if ($action == SQLite3::SELECT) {
13        return SQLite3::OK;
14    }
15
16    return SQLite3::DENY;
17});
18
19// This query should be accepted
20var_dump($db->querySingle('SELECT 1;'));
21
22try {
23    // This one should fail
24    var_dump($db->querySingle('CREATE TABLE test (a, b);'));
25} catch (\Exception $e) {
26    echo $e->getMessage() . "\n";
27}
28
29// Test disabling the authorizer
30$db->setAuthorizer(null);
31
32// This should now succeed
33var_dump($db->exec('CREATE TABLE test (a); INSERT INTO test VALUES (42);'));
34var_dump($db->querySingle('SELECT a FROM test;'));
35
36// Test if we are getting the correct arguments
37$db->setAuthorizer(function (int $action) {
38    $constants = (new ReflectionClass('SQLite3'))->getConstants();
39    $constants = array_flip($constants);
40
41    var_dump($constants[$action], implode(',', array_slice(func_get_args(), 1)));
42    return SQLITE3::OK;
43});
44
45var_dump($db->exec('SELECT * FROM test WHERE a = 42;'));
46var_dump($db->exec('DROP TABLE test;'));
47
48// Try to return something invalid from the authorizer
49$db->setAuthorizer(function () {
50    return 'FAIL';
51});
52
53try {
54    var_dump($db->querySingle('SELECT 1;'));
55} catch (\Exception $e) {
56    echo $e->getMessage() . "\n";
57    echo $e->getPrevious()->getMessage() . "\n";
58}
59
60$db->setAuthorizer(function () {
61    return 4200;
62});
63
64try {
65    var_dump($db->querySingle('SELECT 1;'));
66} catch (\Exception $e) {
67    echo $e->getMessage() . "\n";
68    echo $e->getPrevious()->getMessage() . "\n";
69}
70
71?>
72--EXPECT--
73int(1)
74Unable to prepare statement: 23, not authorized
75bool(true)
76int(42)
77string(6) "SELECT"
78string(3) ",,,"
79string(4) "READ"
80string(12) "test,a,main,"
81string(4) "READ"
82string(12) "test,a,main,"
83bool(true)
84string(6) "DELETE"
85string(20) "sqlite_master,,main,"
86string(10) "DROP_TABLE"
87string(11) "test,,main,"
88string(6) "DELETE"
89string(11) "test,,main,"
90string(6) "DELETE"
91string(20) "sqlite_master,,main,"
92string(4) "READ"
93string(28) "sqlite_master,tbl_name,main,"
94string(4) "READ"
95string(24) "sqlite_master,type,main,"
96string(6) "UPDATE"
97string(28) "sqlite_master,rootpage,main,"
98string(4) "READ"
99string(28) "sqlite_master,rootpage,main,"
100bool(true)
101Unable to prepare statement: 23, not authorized
102The authorizer callback returned an invalid type: expected int
103Unable to prepare statement: 23, not authorized
104The authorizer callback returned an invalid value
105