1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Scott MacVicar <scottmac@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "php.h"
22 #include "php_ini.h"
23 #include "ext/standard/info.h"
24 #include "php_sqlite3.h"
25 #include "php_sqlite3_structs.h"
26 #include "main/SAPI.h"
27
28 #include <sqlite3.h>
29
30 #include "zend_exceptions.h"
31 #include "SAPI.h"
32 #include "sqlite3_arginfo.h"
33
34 ZEND_DECLARE_MODULE_GLOBALS(sqlite3)
35
36 static PHP_GINIT_FUNCTION(sqlite3);
37 static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4);
38 static void sqlite3_param_dtor(zval *data);
39 static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement);
40
41 #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \
42 if (!(db_obj) || !(member)) { \
43 zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \
44 RETURN_THROWS(); \
45 }
46
47 #define SQLITE3_CHECK_INITIALIZED_STMT(member, class_name) \
48 if (!(member)) { \
49 zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \
50 RETURN_THROWS(); \
51 }
52
53 /* {{{ PHP_INI */
54 PHP_INI_BEGIN()
55 STD_PHP_INI_ENTRY("sqlite3.extension_dir", NULL, PHP_INI_SYSTEM, OnUpdateString, extension_dir, zend_sqlite3_globals, sqlite3_globals)
56 #if SQLITE_VERSION_NUMBER >= 3026000
57 STD_PHP_INI_BOOLEAN("sqlite3.defensive", "1", PHP_INI_USER, OnUpdateBool, dbconfig_defensive, zend_sqlite3_globals, sqlite3_globals)
58 #endif
59 PHP_INI_END()
60 /* }}} */
61
62 /* Handlers */
63 static zend_object_handlers sqlite3_object_handlers;
64 static zend_object_handlers sqlite3_stmt_object_handlers;
65 static zend_object_handlers sqlite3_result_object_handlers;
66
67 /* Class entries */
68 zend_class_entry *php_sqlite3_exception_ce;
69 zend_class_entry *php_sqlite3_sc_entry;
70 zend_class_entry *php_sqlite3_stmt_entry;
71 zend_class_entry *php_sqlite3_result_entry;
72
73 /* {{{ Error Handler */
php_sqlite3_error(php_sqlite3_db_object * db_obj,int errcode,const char * format,...)74 static void php_sqlite3_error(php_sqlite3_db_object *db_obj, int errcode, const char *format, ...)
75 {
76 va_list arg;
77 char *message;
78
79 va_start(arg, format);
80 vspprintf(&message, 0, format, arg);
81 va_end(arg);
82
83 if (db_obj && db_obj->exception) {
84 zend_throw_exception(php_sqlite3_exception_ce, message, errcode);
85 } else {
86 php_error_docref(NULL, E_WARNING, "%s", message);
87 }
88
89 if (message) {
90 efree(message);
91 }
92 }
93 /* }}} */
94
95 /* {{{ Opens a SQLite 3 Database, if the build includes encryption then it will attempt to use the key. */
PHP_METHOD(SQLite3,open)96 PHP_METHOD(SQLite3, open)
97 {
98 php_sqlite3_db_object *db_obj;
99 zval *object = ZEND_THIS;
100 char *filename, *encryption_key, *fullpath;
101 size_t filename_len, encryption_key_len = 0;
102 zend_long flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
103 int rc;
104
105 db_obj = Z_SQLITE3_DB_P(object);
106
107 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "p|ls", &filename, &filename_len, &flags, &encryption_key, &encryption_key_len)) {
108 RETURN_THROWS();
109 }
110
111 if (db_obj->initialised) {
112 zend_throw_exception(zend_ce_exception, "Already initialised DB Object", 0);
113 RETURN_THROWS();
114 }
115
116 if (filename_len != 0 && (filename_len != sizeof(":memory:")-1 ||
117 memcmp(filename, ":memory:", sizeof(":memory:")-1) != 0)) {
118 if (!(fullpath = expand_filepath(filename, NULL))) {
119 zend_throw_exception(zend_ce_exception, "Unable to expand filepath", 0);
120 RETURN_THROWS();
121 }
122
123 if (php_check_open_basedir(fullpath)) {
124 zend_throw_exception_ex(zend_ce_exception, 0, "open_basedir prohibits opening %s", fullpath);
125 efree(fullpath);
126 RETURN_THROWS();
127 }
128 } else {
129 /* filename equals "" or ":memory:" */
130 fullpath = filename;
131 }
132
133 rc = sqlite3_open_v2(fullpath, &(db_obj->db), flags, NULL);
134 if (rc != SQLITE_OK) {
135 zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s",
136 #ifdef HAVE_SQLITE3_ERRSTR
137 db_obj->db ? sqlite3_errmsg(db_obj->db) : sqlite3_errstr(rc));
138 #else
139 db_obj->db ? sqlite3_errmsg(db_obj->db) : "");
140 #endif
141 sqlite3_close(db_obj->db);
142 if (fullpath != filename) {
143 efree(fullpath);
144 }
145 return;
146 }
147
148 #ifdef SQLITE_HAS_CODEC
149 if (encryption_key_len > 0) {
150 if (sqlite3_key(db_obj->db, encryption_key, encryption_key_len) != SQLITE_OK) {
151 zend_throw_exception_ex(zend_ce_exception, 0, "Unable to open database: %s", sqlite3_errmsg(db_obj->db));
152 sqlite3_close(db_obj->db);
153 RETURN_THROWS();
154 }
155 }
156 #endif
157
158 db_obj->initialised = 1;
159 db_obj->authorizer_fcc = empty_fcall_info_cache;
160
161 sqlite3_set_authorizer(db_obj->db, php_sqlite3_authorizer, db_obj);
162
163 #if SQLITE_VERSION_NUMBER >= 3026000
164 if (SQLITE3G(dbconfig_defensive)) {
165 sqlite3_db_config(db_obj->db, SQLITE_DBCONFIG_DEFENSIVE, 1, NULL);
166 }
167 #endif
168
169 if (fullpath != filename) {
170 efree(fullpath);
171 }
172 }
173 /* }}} */
174
175 /* {{{ Close a SQLite 3 Database. */
PHP_METHOD(SQLite3,close)176 PHP_METHOD(SQLite3, close)
177 {
178 php_sqlite3_db_object *db_obj;
179 zval *object = ZEND_THIS;
180 int errcode;
181 db_obj = Z_SQLITE3_DB_P(object);
182
183 if (zend_parse_parameters_none() == FAILURE) {
184 RETURN_THROWS();
185 }
186
187 if (db_obj->initialised) {
188 zend_llist_clean(&(db_obj->free_list));
189 if(db_obj->db) {
190 errcode = sqlite3_close(db_obj->db);
191 if (errcode != SQLITE_OK) {
192 php_sqlite3_error(db_obj, errcode, "Unable to close database: %s", sqlite3_errmsg(db_obj->db));
193 RETURN_FALSE;
194 }
195 }
196 db_obj->initialised = 0;
197 }
198
199 RETURN_TRUE;
200 }
201 /* }}} */
202
203 /* {{{ Executes a result-less query against a given database. */
PHP_METHOD(SQLite3,exec)204 PHP_METHOD(SQLite3, exec)
205 {
206 php_sqlite3_db_object *db_obj;
207 zval *object = ZEND_THIS;
208 int errcode;
209 zend_string *sql;
210 char *errtext = NULL;
211 db_obj = Z_SQLITE3_DB_P(object);
212
213 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
214 RETURN_THROWS();
215 }
216
217 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
218
219 errcode = sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext);
220
221 if (errcode != SQLITE_OK) {
222 php_sqlite3_error(db_obj, errcode, "%s", errtext);
223 sqlite3_free(errtext);
224 RETURN_FALSE;
225 }
226
227 RETURN_TRUE;
228 }
229 /* }}} */
230
231 /* {{{ Returns the SQLite3 Library version as a string constant and as a number. */
PHP_METHOD(SQLite3,version)232 PHP_METHOD(SQLite3, version)
233 {
234 if (zend_parse_parameters_none() == FAILURE) {
235 RETURN_THROWS();
236 }
237
238 array_init(return_value);
239
240 add_assoc_string(return_value, "versionString", (char*)sqlite3_libversion());
241 add_assoc_long(return_value, "versionNumber", sqlite3_libversion_number());
242
243 return;
244 }
245 /* }}} */
246
247 /* {{{ Returns the rowid of the most recent INSERT into the database from the database connection. */
PHP_METHOD(SQLite3,lastInsertRowID)248 PHP_METHOD(SQLite3, lastInsertRowID)
249 {
250 php_sqlite3_db_object *db_obj;
251 zval *object = ZEND_THIS;
252 db_obj = Z_SQLITE3_DB_P(object);
253
254 if (zend_parse_parameters_none() == FAILURE) {
255 RETURN_THROWS();
256 }
257
258 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
259
260 RETURN_LONG((zend_long) sqlite3_last_insert_rowid(db_obj->db));
261 }
262 /* }}} */
263
264 /* {{{ Returns the numeric result code of the most recent failed sqlite API call for the database connection. */
PHP_METHOD(SQLite3,lastErrorCode)265 PHP_METHOD(SQLite3, lastErrorCode)
266 {
267 php_sqlite3_db_object *db_obj;
268 zval *object = ZEND_THIS;
269 db_obj = Z_SQLITE3_DB_P(object);
270
271 if (zend_parse_parameters_none() == FAILURE) {
272 RETURN_THROWS();
273 }
274
275 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
276
277 if (db_obj->initialised) {
278 RETURN_LONG(sqlite3_errcode(db_obj->db));
279 } else {
280 RETURN_LONG(0);
281 }
282 }
283 /* }}} */
284
285 /* {{{ Returns the numeric extended result code of the most recent failed sqlite API call for the database connection. */
PHP_METHOD(SQLite3,lastExtendedErrorCode)286 PHP_METHOD(SQLite3, lastExtendedErrorCode)
287 {
288 php_sqlite3_db_object *db_obj;
289 zval *object = ZEND_THIS;
290 db_obj = Z_SQLITE3_DB_P(object);
291
292 if (zend_parse_parameters_none() == FAILURE) {
293 RETURN_THROWS();
294 }
295
296 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
297
298 if (db_obj->initialised) {
299 RETURN_LONG(sqlite3_extended_errcode(db_obj->db));
300 } else {
301 RETURN_LONG(0);
302 }
303 }
304 /* }}} */
305
306 /* {{{ Turns on or off the extended result codes feature of SQLite. */
PHP_METHOD(SQLite3,enableExtendedResultCodes)307 PHP_METHOD(SQLite3, enableExtendedResultCodes)
308 {
309 php_sqlite3_db_object *db_obj;
310 zval *object = ZEND_THIS;
311 bool enable = 1;
312 db_obj = Z_SQLITE3_DB_P(object);
313 int ret;
314
315 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enable) == FAILURE) {
316 RETURN_THROWS();
317 }
318
319 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
320
321 if (db_obj->initialised) {
322 ret = sqlite3_extended_result_codes(db_obj->db, enable ? 1 : 0);
323 if (ret == SQLITE_OK)
324 {
325 RETURN_TRUE;
326 }
327 }
328
329 RETURN_FALSE;
330 }
331 /* }}} */
332
333 /* {{{ Returns english text describing the most recent failed sqlite API call for the database connection. */
PHP_METHOD(SQLite3,lastErrorMsg)334 PHP_METHOD(SQLite3, lastErrorMsg)
335 {
336 php_sqlite3_db_object *db_obj;
337 zval *object = ZEND_THIS;
338 db_obj = Z_SQLITE3_DB_P(object);
339
340 if (zend_parse_parameters_none() == FAILURE) {
341 RETURN_THROWS();
342 }
343
344 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->db, SQLite3)
345
346 if (db_obj->initialised) {
347 RETURN_STRING((char *)sqlite3_errmsg(db_obj->db));
348 } else {
349 RETURN_EMPTY_STRING();
350 }
351 }
352 /* }}} */
353
354 /* {{{ Sets a busy handler that will sleep until database is not locked or timeout is reached. Passing a value less than or equal to zero turns off all busy handlers. */
PHP_METHOD(SQLite3,busyTimeout)355 PHP_METHOD(SQLite3, busyTimeout)
356 {
357 php_sqlite3_db_object *db_obj;
358 zval *object = ZEND_THIS;
359 zend_long ms;
360 #ifdef SQLITE_ENABLE_API_ARMOR
361 int return_code;
362 #endif
363 db_obj = Z_SQLITE3_DB_P(object);
364
365 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "l", &ms)) {
366 RETURN_THROWS();
367 }
368
369 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
370
371 #ifdef SQLITE_ENABLE_API_ARMOR
372 return_code = sqlite3_busy_timeout(db_obj->db, ms);
373 if (return_code != SQLITE_OK) {
374 php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to set busy timeout: %s", sqlite3_errmsg(db_obj->db));
375 RETURN_FALSE;
376 }
377 #else
378 php_ignore_value(sqlite3_busy_timeout(db_obj->db, ms));
379 #endif
380
381 RETURN_TRUE;
382 }
383 /* }}} */
384
385
386 #ifndef SQLITE_OMIT_LOAD_EXTENSION
387 /* {{{ Attempts to load an SQLite extension library. */
PHP_METHOD(SQLite3,loadExtension)388 PHP_METHOD(SQLite3, loadExtension)
389 {
390 php_sqlite3_db_object *db_obj;
391 zval *object = ZEND_THIS;
392 char *extension, *lib_path, *extension_dir, *errtext = NULL;
393 char fullpath[MAXPATHLEN];
394 size_t extension_len, extension_dir_len;
395 db_obj = Z_SQLITE3_DB_P(object);
396
397 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &extension, &extension_len)) {
398 RETURN_THROWS();
399 }
400
401 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
402
403 #ifdef ZTS
404 if ((strncmp(sapi_module.name, "cgi", 3) != 0) &&
405 (strcmp(sapi_module.name, "cli") != 0) &&
406 (strncmp(sapi_module.name, "embed", 5) != 0)
407 ) { php_sqlite3_error(db_obj, 0, "Not supported in multithreaded Web servers");
408 RETURN_FALSE;
409 }
410 #endif
411
412 if (!SQLITE3G(extension_dir)) {
413 php_sqlite3_error(db_obj, 0, "SQLite Extensions are disabled");
414 RETURN_FALSE;
415 }
416
417 if (extension_len == 0) {
418 zend_argument_value_error(1, "cannot be empty");
419 RETURN_THROWS();
420 }
421
422 extension_dir = SQLITE3G(extension_dir);
423 extension_dir_len = strlen(SQLITE3G(extension_dir));
424
425 if (IS_SLASH(extension_dir[extension_dir_len-1])) {
426 spprintf(&lib_path, 0, "%s%s", extension_dir, extension);
427 } else {
428 spprintf(&lib_path, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, extension);
429 }
430
431 if (!VCWD_REALPATH(lib_path, fullpath)) {
432 php_sqlite3_error(db_obj, 0, "Unable to load extension at '%s'", lib_path);
433 efree(lib_path);
434 RETURN_FALSE;
435 }
436
437 efree(lib_path);
438
439 if (strncmp(fullpath, extension_dir, extension_dir_len) != 0) {
440 php_sqlite3_error(db_obj, 0, "Unable to open extensions outside the defined directory");
441 RETURN_FALSE;
442 }
443
444 /* Extension loading should only be enabled for when we attempt to load */
445 sqlite3_enable_load_extension(db_obj->db, 1);
446 if (sqlite3_load_extension(db_obj->db, fullpath, 0, &errtext) != SQLITE_OK) {
447 php_sqlite3_error(db_obj, 0, "%s", errtext);
448 sqlite3_free(errtext);
449 sqlite3_enable_load_extension(db_obj->db, 0);
450 RETURN_FALSE;
451 }
452 sqlite3_enable_load_extension(db_obj->db, 0);
453
454 RETURN_TRUE;
455 }
456 /* }}} */
457 #endif
458
459 /* {{{ Returns the number of database rows that were changed (or inserted or deleted) by the most recent SQL statement. */
PHP_METHOD(SQLite3,changes)460 PHP_METHOD(SQLite3, changes)
461 {
462 php_sqlite3_db_object *db_obj;
463 zval *object = ZEND_THIS;
464 db_obj = Z_SQLITE3_DB_P(object);
465
466 if (zend_parse_parameters_none() == FAILURE) {
467 RETURN_THROWS();
468 }
469
470 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
471
472 RETURN_LONG(sqlite3_changes(db_obj->db));
473 }
474 /* }}} */
475
476 /* {{{ Returns a string that has been properly escaped. */
PHP_METHOD(SQLite3,escapeString)477 PHP_METHOD(SQLite3, escapeString)
478 {
479 zend_string *sql;
480 char *ret;
481
482 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
483 RETURN_THROWS();
484 }
485
486 if (ZSTR_LEN(sql)) {
487 ret = sqlite3_mprintf("%q", ZSTR_VAL(sql));
488 if (ret) {
489 RETVAL_STRING(ret);
490 sqlite3_free(ret);
491 }
492 } else {
493 RETURN_EMPTY_STRING();
494 }
495 }
496 /* }}} */
497
498 /* {{{ Returns a prepared SQL statement for execution. */
PHP_METHOD(SQLite3,prepare)499 PHP_METHOD(SQLite3, prepare)
500 {
501 php_sqlite3_db_object *db_obj;
502 php_sqlite3_stmt *stmt_obj;
503 zval *object = ZEND_THIS;
504 zend_string *sql;
505 int errcode;
506 php_sqlite3_free_list *free_item;
507
508 db_obj = Z_SQLITE3_DB_P(object);
509
510 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
511 RETURN_THROWS();
512 }
513
514 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
515
516 if (!ZSTR_LEN(sql)) {
517 RETURN_FALSE;
518 }
519
520 object_init_ex(return_value, php_sqlite3_stmt_entry);
521 stmt_obj = Z_SQLITE3_STMT_P(return_value);
522 stmt_obj->db_obj = db_obj;
523 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object));
524
525 errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
526 if (errcode != SQLITE_OK) {
527 php_sqlite3_error(db_obj, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
528 zval_ptr_dtor(return_value);
529 RETURN_FALSE;
530 }
531
532 stmt_obj->initialised = 1;
533
534 free_item = emalloc(sizeof(php_sqlite3_free_list));
535 free_item->stmt_obj = stmt_obj;
536 ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(return_value));
537
538 zend_llist_add_element(&(db_obj->free_list), &free_item);
539 }
540 /* }}} */
541
542 /* {{{ Returns true or false, for queries that return data it will return a SQLite3Result object. */
PHP_METHOD(SQLite3,query)543 PHP_METHOD(SQLite3, query)
544 {
545 php_sqlite3_db_object *db_obj;
546 php_sqlite3_result *result;
547 php_sqlite3_stmt *stmt_obj;
548 zval *object = ZEND_THIS;
549 zval stmt;
550 zend_string *sql;
551 char *errtext = NULL;
552 int return_code;
553 db_obj = Z_SQLITE3_DB_P(object);
554
555 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
556 RETURN_THROWS();
557 }
558
559 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
560
561 if (!ZSTR_LEN(sql)) {
562 RETURN_FALSE;
563 }
564
565 /* If there was no return value then just execute the query */
566 if (!USED_RET()) {
567 int errcode;
568 errcode = sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext);
569 if (errcode != SQLITE_OK) {
570 php_sqlite3_error(db_obj, errcode, "%s", errtext);
571 sqlite3_free(errtext);
572 }
573 RETURN_FALSE;
574 }
575
576 object_init_ex(&stmt, php_sqlite3_stmt_entry);
577 stmt_obj = Z_SQLITE3_STMT_P(&stmt);
578 stmt_obj->db_obj = db_obj;
579 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(object));
580
581 return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
582 if (return_code != SQLITE_OK) {
583 php_sqlite3_error(db_obj, return_code, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
584 zval_ptr_dtor(&stmt);
585 RETURN_FALSE;
586 }
587
588 stmt_obj->initialised = 1;
589
590 object_init_ex(return_value, php_sqlite3_result_entry);
591 result = Z_SQLITE3_RESULT_P(return_value);
592 result->db_obj = db_obj;
593 result->stmt_obj = stmt_obj;
594 result->column_names = NULL;
595 result->column_count = -1;
596 ZVAL_OBJ(&result->stmt_obj_zval, Z_OBJ(stmt));
597
598 return_code = sqlite3_step(result->stmt_obj->stmt);
599
600 switch (return_code) {
601 case SQLITE_ROW: /* Valid Row */
602 case SQLITE_DONE: /* Valid but no results */
603 {
604 php_sqlite3_free_list *free_item;
605 free_item = emalloc(sizeof(php_sqlite3_free_list));
606 free_item->stmt_obj = stmt_obj;
607 free_item->stmt_obj_zval = stmt;
608 zend_llist_add_element(&(db_obj->free_list), &free_item);
609 sqlite3_reset(result->stmt_obj->stmt);
610 break;
611 }
612 default:
613 if (!EG(exception)) {
614 php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
615 }
616 sqlite3_finalize(stmt_obj->stmt);
617 stmt_obj->initialised = 0;
618 zval_ptr_dtor(return_value);
619 RETURN_FALSE;
620 }
621 }
622 /* }}} */
623
sqlite_value_to_zval(sqlite3_stmt * stmt,int column,zval * data)624 static void sqlite_value_to_zval(sqlite3_stmt *stmt, int column, zval *data) /* {{{ */
625 {
626 sqlite3_int64 val;
627
628 switch (sqlite3_column_type(stmt, column)) {
629 case SQLITE_INTEGER:
630 val = sqlite3_column_int64(stmt, column);
631 #if LONG_MAX <= 2147483647
632 if (val > ZEND_LONG_MAX || val < ZEND_LONG_MIN) {
633 ZVAL_STRINGL(data, (char *)sqlite3_column_text(stmt, column), sqlite3_column_bytes(stmt, column));
634 } else {
635 #endif
636 ZVAL_LONG(data, (zend_long) val);
637 #if LONG_MAX <= 2147483647
638 }
639 #endif
640 break;
641
642 case SQLITE_FLOAT:
643 ZVAL_DOUBLE(data, sqlite3_column_double(stmt, column));
644 break;
645
646 case SQLITE_NULL:
647 ZVAL_NULL(data);
648 break;
649
650 case SQLITE3_TEXT:
651 ZVAL_STRING(data, (char*)sqlite3_column_text(stmt, column));
652 break;
653
654 case SQLITE_BLOB:
655 default:
656 ZVAL_STRINGL(data, (char*)sqlite3_column_blob(stmt, column), sqlite3_column_bytes(stmt, column));
657 }
658 }
659 /* }}} */
660
661 /* {{{ Returns a string of the first column, or an array of the entire row. */
PHP_METHOD(SQLite3,querySingle)662 PHP_METHOD(SQLite3, querySingle)
663 {
664 php_sqlite3_db_object *db_obj;
665 zval *object = ZEND_THIS;
666 zend_string *sql;
667 char *errtext = NULL;
668 int return_code;
669 bool entire_row = 0;
670 sqlite3_stmt *stmt;
671 db_obj = Z_SQLITE3_DB_P(object);
672
673 if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &sql, &entire_row)) {
674 RETURN_THROWS();
675 }
676
677 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
678
679 if (!ZSTR_LEN(sql)) {
680 RETURN_FALSE;
681 }
682
683 /* If there was no return value then just execute the query */
684 if (!USED_RET()) {
685 int errcode;
686 errcode = sqlite3_exec(db_obj->db, ZSTR_VAL(sql), NULL, NULL, &errtext);
687 if (errcode != SQLITE_OK) {
688 php_sqlite3_error(db_obj, errcode, "%s", errtext);
689 sqlite3_free(errtext);
690 }
691 RETURN_FALSE;
692 }
693
694 return_code = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &stmt, NULL);
695 if (return_code != SQLITE_OK) {
696 php_sqlite3_error(db_obj, return_code, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
697 RETURN_FALSE;
698 }
699
700 return_code = sqlite3_step(stmt);
701
702 switch (return_code) {
703 case SQLITE_ROW: /* Valid Row */
704 {
705 if (!entire_row) {
706 sqlite_value_to_zval(stmt, 0, return_value);
707 } else {
708 int i = 0;
709 array_init(return_value);
710 for (i = 0; i < sqlite3_data_count(stmt); i++) {
711 zval data;
712 sqlite_value_to_zval(stmt, i, &data);
713 add_assoc_zval(return_value, (char*)sqlite3_column_name(stmt, i), &data);
714 }
715 }
716 break;
717 }
718 case SQLITE_DONE: /* Valid but no results */
719 {
720 if (!entire_row) {
721 RETVAL_NULL();
722 } else {
723 RETVAL_EMPTY_ARRAY();
724 }
725 break;
726 }
727 default:
728 if (!EG(exception)) {
729 php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to execute statement: %s", sqlite3_errmsg(db_obj->db));
730 }
731 RETVAL_FALSE;
732 }
733 sqlite3_finalize(stmt);
734 }
735 /* }}} */
736
sqlite3_do_callback(zend_fcall_info_cache * fcc,uint32_t argc,sqlite3_value ** argv,sqlite3_context * context,int is_agg)737 static int sqlite3_do_callback(zend_fcall_info_cache *fcc, uint32_t argc, sqlite3_value **argv, sqlite3_context *context, int is_agg) /* {{{ */
738 {
739 zval *zargs = NULL;
740 zval retval;
741 uint32_t i;
742 uint32_t fake_argc;
743 zend_result ret = SUCCESS;
744 php_sqlite3_agg_context *agg_context = NULL;
745
746 if (is_agg) {
747 is_agg = 2;
748 }
749
750 fake_argc = argc + is_agg;
751
752 /* build up the params */
753 if (fake_argc) {
754 zargs = (zval *)safe_emalloc(fake_argc, sizeof(zval), 0);
755 }
756
757 if (is_agg) {
758 /* summon the aggregation context */
759 agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
760
761 if (Z_ISUNDEF(agg_context->zval_context)) {
762 ZVAL_NULL(&agg_context->zval_context);
763 }
764 ZVAL_COPY(&zargs[0], &agg_context->zval_context);
765 ZVAL_LONG(&zargs[1], agg_context->row_count);
766 }
767
768 for (i = 0; i < argc; i++) {
769 switch (sqlite3_value_type(argv[i])) {
770 case SQLITE_INTEGER:
771 #if ZEND_LONG_MAX > 2147483647
772 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int64(argv[i]));
773 #else
774 ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
775 #endif
776 break;
777
778 case SQLITE_FLOAT:
779 ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
780 break;
781
782 case SQLITE_NULL:
783 ZVAL_NULL(&zargs[i + is_agg]);
784 break;
785
786 case SQLITE_BLOB:
787 case SQLITE3_TEXT:
788 default:
789 ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
790 break;
791 }
792 }
793
794 zend_call_known_fcc(fcc, &retval, fake_argc, zargs, /* named_params */ NULL);
795
796 /* clean up the params */
797 if (is_agg) {
798 zval_ptr_dtor(&zargs[0]);
799 zval_ptr_dtor(&zargs[1]);
800 }
801 if (fake_argc) {
802 for (i = is_agg; i < argc + is_agg; i++) {
803 zval_ptr_dtor(&zargs[i]);
804 }
805 efree(zargs);
806 }
807
808 if (!is_agg || !argv) {
809 /* only set the sqlite return value if we are a scalar function,
810 * or if we are finalizing an aggregate */
811 if (!Z_ISUNDEF(retval)) {
812 switch (Z_TYPE(retval)) {
813 case IS_LONG:
814 #if ZEND_LONG_MAX > 2147483647
815 sqlite3_result_int64(context, Z_LVAL(retval));
816 #else
817 sqlite3_result_int(context, Z_LVAL(retval));
818 #endif
819 break;
820
821 case IS_NULL:
822 sqlite3_result_null(context);
823 break;
824
825 case IS_DOUBLE:
826 sqlite3_result_double(context, Z_DVAL(retval));
827 break;
828
829 default: {
830 zend_string *str = zval_try_get_string(&retval);
831 if (UNEXPECTED(!str)) {
832 ret = FAILURE;
833 break;
834 }
835 sqlite3_result_text(context, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
836 zend_string_release(str);
837 break;
838 }
839 }
840 } else {
841 sqlite3_result_error(context, "failed to invoke callback", 0);
842 }
843
844 if (agg_context && !Z_ISUNDEF(agg_context->zval_context)) {
845 zval_ptr_dtor(&agg_context->zval_context);
846 }
847 } else {
848 /* we're stepping in an aggregate; the return value goes into
849 * the context */
850 if (agg_context && !Z_ISUNDEF(agg_context->zval_context)) {
851 zval_ptr_dtor(&agg_context->zval_context);
852 }
853 ZVAL_COPY_VALUE(&agg_context->zval_context, &retval);
854 ZVAL_UNDEF(&retval);
855 }
856
857 if (!Z_ISUNDEF(retval)) {
858 zval_ptr_dtor(&retval);
859 }
860 return ret;
861 }
862 /* }}}*/
863
php_sqlite3_callback_func(sqlite3_context * context,int argc,sqlite3_value ** argv)864 static void php_sqlite3_callback_func(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */
865 {
866 php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
867
868 sqlite3_do_callback(&func->func, argc, argv, context, 0);
869 }
870 /* }}}*/
871
php_sqlite3_callback_step(sqlite3_context * context,int argc,sqlite3_value ** argv)872 static void php_sqlite3_callback_step(sqlite3_context *context, int argc, sqlite3_value **argv) /* {{{ */
873 {
874 php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
875 php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
876
877 agg_context->row_count++;
878
879 sqlite3_do_callback(&func->step, argc, argv, context, 1);
880 }
881 /* }}} */
882
php_sqlite3_callback_final(sqlite3_context * context)883 static void php_sqlite3_callback_final(sqlite3_context *context) /* {{{ */
884 {
885 php_sqlite3_func *func = (php_sqlite3_func *)sqlite3_user_data(context);
886 php_sqlite3_agg_context *agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context(context, sizeof(php_sqlite3_agg_context));
887
888 agg_context->row_count = 0;
889
890 sqlite3_do_callback(&func->fini, 0, NULL, context, 1);
891 }
892 /* }}} */
893
php_sqlite3_callback_compare(void * coll,int a_len,const void * a,int b_len,const void * b)894 static int php_sqlite3_callback_compare(void *coll, int a_len, const void *a, int b_len, const void* b) /* {{{ */
895 {
896 php_sqlite3_collation *collation = (php_sqlite3_collation*)coll;
897 zval zargs[2];
898 zval retval;
899 int ret = 0;
900
901 // Exception occurred on previous callback. Don't attempt to call function.
902 if (EG(exception)) {
903 return 0;
904 }
905
906 ZVAL_STRINGL(&zargs[0], a, a_len);
907 ZVAL_STRINGL(&zargs[1], b, b_len);
908
909 zend_call_known_fcc(&collation->cmp_func, &retval, /* argc */ 2, zargs, /* named_params */ NULL);
910
911 zval_ptr_dtor(&zargs[0]);
912 zval_ptr_dtor(&zargs[1]);
913
914 if (EG(exception)) {
915 ret = 0;
916 } else if (Z_TYPE(retval) != IS_LONG){
917 //retval ought to contain a ZVAL_LONG by now
918 // (the result of a comparison, i.e. most likely -1, 0, or 1)
919 //I suppose we could accept any scalar return type, though.
920 php_sqlite3_error(NULL, 0, "An error occurred while invoking the compare callback (invalid return type). Collation behaviour is undefined.");
921 } else {
922 ret = Z_LVAL(retval);
923 }
924
925 zval_ptr_dtor(&retval);
926
927 return ret;
928 }
929 /* }}} */
930
931 /* {{{ Allows registration of a PHP function as a SQLite UDF that can be called within SQL statements. */
PHP_METHOD(SQLite3,createFunction)932 PHP_METHOD(SQLite3, createFunction)
933 {
934 php_sqlite3_db_object *db_obj;
935 zval *object = ZEND_THIS;
936 php_sqlite3_func *func;
937 char *sql_func;
938 size_t sql_func_len;
939 zend_fcall_info fci;
940 zend_fcall_info_cache fcc;
941 zend_long sql_func_num_args = -1;
942 zend_long flags = 0;
943 db_obj = Z_SQLITE3_DB_P(object);
944
945 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sf|ll", &sql_func, &sql_func_len, &fci, &fcc, &sql_func_num_args, &flags) == FAILURE) {
946 RETURN_THROWS();
947 }
948
949 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
950
951 if (!sql_func_len) {
952 RETURN_FALSE;
953 }
954
955 func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
956
957 if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, flags | SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) {
958 func->func_name = estrdup(sql_func);
959
960 if (!ZEND_FCC_INITIALIZED(fcc)) {
961 zend_is_callable_ex(&fci.function_name, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL);
962 /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal
963 * with it outselves. It is important that it is not refetched on every call,
964 * because calls may occur from different scopes. */
965 }
966 zend_fcc_dup(&func->func, &fcc);
967
968 func->argc = sql_func_num_args;
969 func->next = db_obj->funcs;
970 db_obj->funcs = func;
971
972 RETURN_TRUE;
973 }
974 efree(func);
975
976 RETURN_FALSE;
977 }
978 /* }}} */
979
980 /* {{{ Allows registration of a PHP function for use as an aggregate. */
PHP_METHOD(SQLite3,createAggregate)981 PHP_METHOD(SQLite3, createAggregate)
982 {
983 php_sqlite3_db_object *db_obj;
984 zval *object = ZEND_THIS;
985 php_sqlite3_func *func;
986 char *sql_func;
987 size_t sql_func_len;
988 zend_fcall_info step_fci, fini_fci;
989 zend_fcall_info_cache step_fcc, fini_fcc;
990 zend_long sql_func_num_args = -1;
991 db_obj = Z_SQLITE3_DB_P(object);
992
993 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sff|l", &sql_func, &sql_func_len, &step_fci, &step_fcc, &fini_fci, &fini_fcc, &sql_func_num_args) == FAILURE) {
994 RETURN_THROWS();
995 }
996
997 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
998
999 if (!sql_func_len) {
1000 RETURN_FALSE;
1001 }
1002
1003 func = (php_sqlite3_func *)ecalloc(1, sizeof(*func));
1004
1005 if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) {
1006 func->func_name = estrdup(sql_func);
1007
1008 if (!ZEND_FCC_INITIALIZED(step_fcc)) {
1009 /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal
1010 * with it outselves. It is important that it is not refetched on every call,
1011 * because calls may occur from different scopes. */
1012 zend_is_callable_ex(&step_fci.function_name, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &step_fcc, NULL);
1013 }
1014 zend_fcc_dup(&func->step, &step_fcc);
1015 if (!ZEND_FCC_INITIALIZED(fini_fcc)) {
1016 /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal
1017 * with it outselves. It is important that it is not refetched on every call,
1018 * because calls may occur from different scopes. */
1019 zend_is_callable_ex(&fini_fci.function_name, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fini_fcc, NULL);
1020 }
1021 zend_fcc_dup(&func->fini, &fini_fcc);
1022
1023 func->argc = sql_func_num_args;
1024 func->next = db_obj->funcs;
1025 db_obj->funcs = func;
1026
1027 RETURN_TRUE;
1028 }
1029 efree(func);
1030
1031 RETURN_FALSE;
1032 }
1033 /* }}} */
1034
1035 /* {{{ Registers a PHP function as a comparator that can be used with the SQL COLLATE operator. Callback must accept two strings and return an integer (as strcmp()). */
PHP_METHOD(SQLite3,createCollation)1036 PHP_METHOD(SQLite3, createCollation)
1037 {
1038 php_sqlite3_db_object *db_obj;
1039 zval *object = ZEND_THIS;
1040 php_sqlite3_collation *collation;
1041 char *collation_name;
1042 size_t collation_name_len;
1043 zend_fcall_info fci;
1044 zend_fcall_info_cache fcc;
1045 db_obj = Z_SQLITE3_DB_P(object);
1046
1047 if (zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &collation_name, &collation_name_len, &fci, &fcc) == FAILURE) {
1048 RETURN_THROWS();
1049 }
1050
1051 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1052
1053 if (!collation_name_len) {
1054 RETURN_FALSE;
1055 }
1056
1057 collation = (php_sqlite3_collation *)ecalloc(1, sizeof(*collation));
1058 if (sqlite3_create_collation(db_obj->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) {
1059 collation->collation_name = estrdup(collation_name);
1060
1061 if (!ZEND_FCC_INITIALIZED(fcc)) {
1062 /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal
1063 * with it outselves. It is important that it is not refetched on every call,
1064 * because calls may occur from different scopes. */
1065 zend_is_callable_ex(&fci.function_name, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL);
1066 }
1067 zend_fcc_dup(&collation->cmp_func, &fcc);
1068
1069 collation->next = db_obj->collations;
1070 db_obj->collations = collation;
1071
1072 RETURN_TRUE;
1073 }
1074 efree(collation);
1075
1076 RETURN_FALSE;
1077 }
1078 /* }}} */
1079
1080 typedef struct {
1081 sqlite3_blob *blob;
1082 size_t position;
1083 size_t size;
1084 int flags;
1085 } php_stream_sqlite3_data;
1086
php_sqlite3_stream_write(php_stream * stream,const char * buf,size_t count)1087 static ssize_t php_sqlite3_stream_write(php_stream *stream, const char *buf, size_t count)
1088 {
1089 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1090
1091 if (sqlite3_stream->flags & SQLITE_OPEN_READONLY) {
1092 php_sqlite3_error(NULL, 0, "Can't write to blob stream: is open as read only");
1093 return -1;
1094 }
1095
1096 if (sqlite3_stream->position + count > sqlite3_stream->size) {
1097 php_sqlite3_error(NULL, 0, "It is not possible to increase the size of a BLOB");
1098 return -1;
1099 }
1100
1101 if (sqlite3_blob_write(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
1102 return -1;
1103 }
1104
1105 if (sqlite3_stream->position + count >= sqlite3_stream->size) {
1106 stream->eof = 1;
1107 sqlite3_stream->position = sqlite3_stream->size;
1108 }
1109 else {
1110 sqlite3_stream->position += count;
1111 }
1112
1113 return count;
1114 }
1115
php_sqlite3_stream_read(php_stream * stream,char * buf,size_t count)1116 static ssize_t php_sqlite3_stream_read(php_stream *stream, char *buf, size_t count)
1117 {
1118 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1119
1120 if (sqlite3_stream->position + count >= sqlite3_stream->size) {
1121 count = sqlite3_stream->size - sqlite3_stream->position;
1122 stream->eof = 1;
1123 }
1124 if (count) {
1125 if (sqlite3_blob_read(sqlite3_stream->blob, buf, count, sqlite3_stream->position) != SQLITE_OK) {
1126 return -1;
1127 }
1128 sqlite3_stream->position += count;
1129 }
1130 return count;
1131 }
1132
php_sqlite3_stream_close(php_stream * stream,int close_handle)1133 static int php_sqlite3_stream_close(php_stream *stream, int close_handle)
1134 {
1135 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1136
1137 if (sqlite3_blob_close(sqlite3_stream->blob) != SQLITE_OK) {
1138 /* Error occurred, but it still closed */
1139 }
1140
1141 efree(sqlite3_stream);
1142
1143 return 0;
1144 }
1145
php_sqlite3_stream_flush(php_stream * stream)1146 static int php_sqlite3_stream_flush(php_stream *stream)
1147 {
1148 /* do nothing */
1149 return 0;
1150 }
1151
1152 /* {{{ */
php_sqlite3_stream_seek(php_stream * stream,zend_off_t offset,int whence,zend_off_t * newoffs)1153 static int php_sqlite3_stream_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs)
1154 {
1155 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1156
1157 switch(whence) {
1158 case SEEK_CUR:
1159 if (offset < 0) {
1160 if (sqlite3_stream->position < (size_t)(-offset)) {
1161 sqlite3_stream->position = 0;
1162 *newoffs = -1;
1163 return -1;
1164 } else {
1165 sqlite3_stream->position = sqlite3_stream->position + offset;
1166 *newoffs = sqlite3_stream->position;
1167 stream->eof = 0;
1168 return 0;
1169 }
1170 } else {
1171 if (sqlite3_stream->position + (size_t)(offset) > sqlite3_stream->size) {
1172 sqlite3_stream->position = sqlite3_stream->size;
1173 *newoffs = -1;
1174 return -1;
1175 } else {
1176 sqlite3_stream->position = sqlite3_stream->position + offset;
1177 *newoffs = sqlite3_stream->position;
1178 stream->eof = 0;
1179 return 0;
1180 }
1181 }
1182 case SEEK_SET:
1183 if (sqlite3_stream->size < (size_t)(offset)) {
1184 sqlite3_stream->position = sqlite3_stream->size;
1185 *newoffs = -1;
1186 return -1;
1187 } else {
1188 sqlite3_stream->position = offset;
1189 *newoffs = sqlite3_stream->position;
1190 stream->eof = 0;
1191 return 0;
1192 }
1193 case SEEK_END:
1194 if (offset > 0) {
1195 sqlite3_stream->position = sqlite3_stream->size;
1196 *newoffs = -1;
1197 return -1;
1198 } else if (sqlite3_stream->size < (size_t)(-offset)) {
1199 sqlite3_stream->position = 0;
1200 *newoffs = -1;
1201 return -1;
1202 } else {
1203 sqlite3_stream->position = sqlite3_stream->size + offset;
1204 *newoffs = sqlite3_stream->position;
1205 stream->eof = 0;
1206 return 0;
1207 }
1208 default:
1209 *newoffs = sqlite3_stream->position;
1210 return -1;
1211 }
1212 }
1213 /* }}} */
1214
1215
php_sqlite3_stream_cast(php_stream * stream,int castas,void ** ret)1216 static int php_sqlite3_stream_cast(php_stream *stream, int castas, void **ret)
1217 {
1218 return FAILURE;
1219 }
1220
php_sqlite3_stream_stat(php_stream * stream,php_stream_statbuf * ssb)1221 static int php_sqlite3_stream_stat(php_stream *stream, php_stream_statbuf *ssb)
1222 {
1223 php_stream_sqlite3_data *sqlite3_stream = (php_stream_sqlite3_data *) stream->abstract;
1224 ssb->sb.st_size = sqlite3_stream->size;
1225 return 0;
1226 }
1227
1228 static const php_stream_ops php_stream_sqlite3_ops = {
1229 php_sqlite3_stream_write,
1230 php_sqlite3_stream_read,
1231 php_sqlite3_stream_close,
1232 php_sqlite3_stream_flush,
1233 "SQLite3",
1234 php_sqlite3_stream_seek,
1235 php_sqlite3_stream_cast,
1236 php_sqlite3_stream_stat,
1237 NULL
1238 };
1239
1240 /* {{{ Open a blob as a stream which we can read / write to. */
PHP_METHOD(SQLite3,openBlob)1241 PHP_METHOD(SQLite3, openBlob)
1242 {
1243 php_sqlite3_db_object *db_obj;
1244 zval *object = ZEND_THIS;
1245 const char *table, *column, *dbname = "main", *mode = "rb";
1246 size_t table_len, column_len, dbname_len;
1247 zend_long rowid, flags = SQLITE_OPEN_READONLY, sqlite_flags = 0;
1248 sqlite3_blob *blob = NULL;
1249 php_stream_sqlite3_data *sqlite3_stream;
1250 php_stream *stream;
1251
1252 db_obj = Z_SQLITE3_DB_P(object);
1253
1254 if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssl|pl", &table, &table_len, &column, &column_len, &rowid, &dbname, &dbname_len, &flags) == FAILURE) {
1255 RETURN_THROWS();
1256 }
1257
1258 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1259
1260 sqlite_flags = (flags & SQLITE_OPEN_READWRITE) ? 1 : 0;
1261
1262 if (sqlite3_blob_open(db_obj->db, dbname, table, column, rowid, sqlite_flags, &blob) != SQLITE_OK) {
1263 php_sqlite3_error(db_obj, sqlite3_errcode(db_obj->db), "Unable to open blob: %s", sqlite3_errmsg(db_obj->db));
1264 RETURN_FALSE;
1265 }
1266
1267 sqlite3_stream = emalloc(sizeof(php_stream_sqlite3_data));
1268 sqlite3_stream->blob = blob;
1269 sqlite3_stream->flags = flags;
1270 sqlite3_stream->position = 0;
1271 sqlite3_stream->size = sqlite3_blob_bytes(blob);
1272
1273 if (sqlite_flags != 0) {
1274 mode = "r+b";
1275 }
1276
1277 stream = php_stream_alloc(&php_stream_sqlite3_ops, sqlite3_stream, 0, mode);
1278
1279 if (stream) {
1280 php_stream_to_zval(stream, return_value);
1281 } else {
1282 RETURN_FALSE;
1283 }
1284 }
1285 /* }}} */
1286
1287 /* {{{ Enables an exception error mode. */
PHP_METHOD(SQLite3,enableExceptions)1288 PHP_METHOD(SQLite3, enableExceptions)
1289 {
1290 php_sqlite3_db_object *db_obj;
1291 zval *object = ZEND_THIS;
1292 bool enableExceptions = 0;
1293
1294 db_obj = Z_SQLITE3_DB_P(object);
1295
1296 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enableExceptions) == FAILURE) {
1297 RETURN_THROWS();
1298 }
1299
1300 RETVAL_BOOL(db_obj->exception);
1301
1302 if (!enableExceptions) {
1303 php_error_docref("ref.sqlite3", E_DEPRECATED, "Use of warnings for SQLite3 is deprecated");
1304 }
1305
1306 db_obj->exception = enableExceptions;
1307 }
1308 /* }}} */
1309
1310 /* {{{ Register a callback function to be used as an authorizer by SQLite. The callback should return SQLite3::OK, SQLite3::IGNORE or SQLite3::DENY. */
PHP_METHOD(SQLite3,setAuthorizer)1311 PHP_METHOD(SQLite3, setAuthorizer)
1312 {
1313 php_sqlite3_db_object *db_obj;
1314 zval *object = ZEND_THIS;
1315 db_obj = Z_SQLITE3_DB_P(object);
1316 zend_fcall_info fci;
1317 zend_fcall_info_cache fcc;
1318
1319 ZEND_PARSE_PARAMETERS_START(1, 1)
1320 Z_PARAM_FUNC_OR_NULL(fci, fcc)
1321 ZEND_PARSE_PARAMETERS_END();
1322
1323 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1324
1325 /* Clear previously set callback */
1326 if (ZEND_FCC_INITIALIZED(db_obj->authorizer_fcc)) {
1327 zend_fcc_dtor(&db_obj->authorizer_fcc);
1328 }
1329
1330 /* Only enable userland authorizer if argument is not NULL */
1331 if (ZEND_FCI_INITIALIZED(fci)) {
1332 if (!ZEND_FCC_INITIALIZED(fcc)) {
1333 zend_is_callable_ex(&fci.function_name, NULL, IS_CALLABLE_SUPPRESS_DEPRECATIONS, NULL, &fcc, NULL);
1334 /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal
1335 * with it outselves. It is important that it is not refetched on every call,
1336 * because calls may occur from different scopes. */
1337 }
1338 db_obj->authorizer_fcc = fcc;
1339 zend_fcc_addref(&db_obj->authorizer_fcc);
1340 }
1341
1342 RETURN_TRUE;
1343 }
1344 /* }}} */
1345
1346
1347 #if SQLITE_VERSION_NUMBER >= 3006011
1348 /* {{{ Backups the current database to another one. */
PHP_METHOD(SQLite3,backup)1349 PHP_METHOD(SQLite3, backup)
1350 {
1351 php_sqlite3_db_object *source_obj;
1352 php_sqlite3_db_object *destination_obj;
1353 const char *source_dbname = "main", *destination_dbname = "main";
1354 size_t source_dbname_length, destination_dbname_length;
1355 zval *source_zval = ZEND_THIS;
1356 zval *destination_zval;
1357 sqlite3_backup *dbBackup;
1358 int rc; // Return code
1359
1360 if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|pp", &destination_zval, php_sqlite3_sc_entry, &source_dbname, &source_dbname_length, &destination_dbname, &destination_dbname_length) == FAILURE) {
1361 RETURN_THROWS();
1362 }
1363
1364 source_obj = Z_SQLITE3_DB_P(source_zval);
1365 SQLITE3_CHECK_INITIALIZED(source_obj, source_obj->initialised, SQLite3)
1366
1367 destination_obj = Z_SQLITE3_DB_P(destination_zval);
1368
1369 SQLITE3_CHECK_INITIALIZED(destination_obj, destination_obj->initialised, SQLite3)
1370
1371 dbBackup = sqlite3_backup_init(destination_obj->db, destination_dbname, source_obj->db, source_dbname);
1372
1373 if (dbBackup) {
1374 do {
1375 rc = sqlite3_backup_step(dbBackup, -1);
1376 } while (rc == SQLITE_OK);
1377
1378 /* Release resources allocated by backup_init(). */
1379 rc = sqlite3_backup_finish(dbBackup);
1380 }
1381 else {
1382 rc = sqlite3_errcode(source_obj->db);
1383 }
1384
1385 if (rc != SQLITE_OK) {
1386 if (rc == SQLITE_BUSY) {
1387 php_sqlite3_error(source_obj, rc, "Backup failed: source database is busy");
1388 }
1389 else if (rc == SQLITE_LOCKED) {
1390 php_sqlite3_error(source_obj, rc, "Backup failed: source database is locked");
1391 }
1392 else {
1393 php_sqlite3_error(source_obj, rc, "Backup failed: %s", sqlite3_errmsg(source_obj->db));
1394 }
1395 RETURN_FALSE;
1396 }
1397
1398 RETURN_TRUE;
1399 }
1400 /* }}} */
1401 #endif
1402
1403 /* {{{ Returns the number of parameters within the prepared statement. */
PHP_METHOD(SQLite3Stmt,paramCount)1404 PHP_METHOD(SQLite3Stmt, paramCount)
1405 {
1406 php_sqlite3_stmt *stmt_obj;
1407 zval *object = ZEND_THIS;
1408 stmt_obj = Z_SQLITE3_STMT_P(object);
1409
1410 ZEND_PARSE_PARAMETERS_NONE();
1411
1412 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1413 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1414
1415 RETURN_LONG(sqlite3_bind_parameter_count(stmt_obj->stmt));
1416 }
1417 /* }}} */
1418
1419 /* {{{ Closes the prepared statement. */
PHP_METHOD(SQLite3Stmt,close)1420 PHP_METHOD(SQLite3Stmt, close)
1421 {
1422 php_sqlite3_stmt *stmt_obj;
1423 zval *object = ZEND_THIS;
1424 stmt_obj = Z_SQLITE3_STMT_P(object);
1425
1426 ZEND_PARSE_PARAMETERS_NONE();
1427
1428 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1429
1430 zend_llist_del_element(&(stmt_obj->db_obj->free_list), object, (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
1431
1432 RETURN_TRUE;
1433 }
1434 /* }}} */
1435
1436 /* {{{ Reset the prepared statement to the state before it was executed, bindings still remain. */
PHP_METHOD(SQLite3Stmt,reset)1437 PHP_METHOD(SQLite3Stmt, reset)
1438 {
1439 php_sqlite3_stmt *stmt_obj;
1440 zval *object = ZEND_THIS;
1441 stmt_obj = Z_SQLITE3_STMT_P(object);
1442
1443 ZEND_PARSE_PARAMETERS_NONE();
1444
1445 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1446 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1447
1448 if (sqlite3_reset(stmt_obj->stmt) != SQLITE_OK) {
1449 php_sqlite3_error(stmt_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(stmt_obj->stmt)), "Unable to reset statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
1450 RETURN_FALSE;
1451 }
1452 RETURN_TRUE;
1453 }
1454 /* }}} */
1455
1456 /* {{{ Clear all current bound parameters. */
PHP_METHOD(SQLite3Stmt,clear)1457 PHP_METHOD(SQLite3Stmt, clear)
1458 {
1459 php_sqlite3_stmt *stmt_obj;
1460 zval *object = ZEND_THIS;
1461 stmt_obj = Z_SQLITE3_STMT_P(object);
1462
1463 ZEND_PARSE_PARAMETERS_NONE();
1464
1465 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1466 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1467
1468 if (sqlite3_clear_bindings(stmt_obj->stmt) != SQLITE_OK) {
1469 php_sqlite3_error(stmt_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(stmt_obj->stmt)), "Unable to clear statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
1470 RETURN_FALSE;
1471 }
1472
1473 if (stmt_obj->bound_params) {
1474 zend_hash_destroy(stmt_obj->bound_params);
1475 FREE_HASHTABLE(stmt_obj->bound_params);
1476 stmt_obj->bound_params = NULL;
1477 }
1478
1479 RETURN_TRUE;
1480 }
1481 /* }}} */
1482
1483 /* {{{ Returns true if a statement is definitely read only */
PHP_METHOD(SQLite3Stmt,readOnly)1484 PHP_METHOD(SQLite3Stmt, readOnly)
1485 {
1486 php_sqlite3_stmt *stmt_obj;
1487 zval *object = ZEND_THIS;
1488 stmt_obj = Z_SQLITE3_STMT_P(object);
1489
1490 ZEND_PARSE_PARAMETERS_NONE();
1491
1492 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1493 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1494
1495 if (sqlite3_stmt_readonly(stmt_obj->stmt)) {
1496 RETURN_TRUE;
1497 }
1498 RETURN_FALSE;
1499 }
1500 /* }}} */
1501
1502 /* bind parameters to a statement before execution */
php_sqlite3_bind_params(php_sqlite3_stmt * stmt_obj)1503 static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
1504 {
1505 struct php_sqlite3_bound_param *param;
1506 int return_code;
1507
1508 if (stmt_obj->bound_params) {
1509 ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
1510 zval *parameter;
1511 /* parameter must be a reference? */
1512 if (Z_ISREF(param->parameter)) {
1513 parameter = Z_REFVAL(param->parameter);
1514 } else {
1515 parameter = ¶m->parameter;
1516 }
1517
1518 /* If the ZVAL is null then it should be bound as that */
1519 if (Z_TYPE_P(parameter) == IS_NULL) {
1520 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1521 if (return_code != SQLITE_OK) {
1522 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1523 }
1524 continue;
1525 }
1526
1527 switch (param->type) {
1528 case SQLITE_INTEGER:
1529 convert_to_long(parameter);
1530 #if ZEND_LONG_MAX > 2147483647
1531 return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
1532 #else
1533 return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
1534 #endif
1535 if (return_code != SQLITE_OK) {
1536 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1537 }
1538 break;
1539
1540 case SQLITE_FLOAT:
1541 convert_to_double(parameter);
1542 return_code = sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter));
1543 if (return_code != SQLITE_OK) {
1544 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1545 }
1546 break;
1547
1548 case SQLITE_BLOB:
1549 {
1550 php_stream *stream = NULL;
1551 zend_string *buffer = NULL;
1552 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
1553 php_stream_from_zval_no_verify(stream, parameter);
1554 if (stream == NULL) {
1555 php_sqlite3_error(stmt_obj->db_obj, 0, "Unable to read stream for parameter %ld", param->param_number);
1556 return FAILURE;
1557 }
1558 buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
1559 } else {
1560 buffer = zval_get_string(parameter);
1561 }
1562
1563 if (buffer) {
1564 return_code = sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT);
1565 zend_string_release_ex(buffer, 0);
1566 if (return_code != SQLITE_OK) {
1567 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1568 }
1569 } else {
1570 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1571 if (return_code != SQLITE_OK) {
1572 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1573 }
1574 }
1575 break;
1576 }
1577
1578 case SQLITE3_TEXT: {
1579 zend_string *str = zval_try_get_string(parameter);
1580 if (UNEXPECTED(!str)) {
1581 return FAILURE;
1582 }
1583 return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
1584 if (return_code != SQLITE_OK) {
1585 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1586 }
1587 zend_string_release(str);
1588 break;
1589 }
1590
1591 case SQLITE_NULL:
1592 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1593 if (return_code != SQLITE_OK) {
1594 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1595 }
1596 break;
1597
1598 default:
1599 php_sqlite3_error(stmt_obj->db_obj, 0, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
1600 return FAILURE;
1601 }
1602 } ZEND_HASH_FOREACH_END();
1603 }
1604
1605 return SUCCESS;
1606 }
1607 /* }}} */
1608
1609
1610 /* {{{ Returns the SQL statement used to prepare the query. If expanded is true, binded parameters and values will be expanded. */
PHP_METHOD(SQLite3Stmt,getSQL)1611 PHP_METHOD(SQLite3Stmt, getSQL)
1612 {
1613 php_sqlite3_stmt *stmt_obj;
1614 bool expanded = 0;
1615 zval *object = ZEND_THIS;
1616 stmt_obj = Z_SQLITE3_STMT_P(object);
1617 int bind_rc;
1618
1619 ZEND_PARSE_PARAMETERS_START(0, 1)
1620 Z_PARAM_OPTIONAL
1621 Z_PARAM_BOOL(expanded)
1622 ZEND_PARSE_PARAMETERS_END();
1623
1624 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1625 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1626
1627 bind_rc = php_sqlite3_bind_params(stmt_obj);
1628
1629 if (bind_rc == FAILURE || EG(exception)) {
1630 RETURN_FALSE;
1631 }
1632
1633 if (expanded) {
1634 #ifdef HAVE_SQLITE3_EXPANDED_SQL
1635 char *sql = sqlite3_expanded_sql(stmt_obj->stmt);
1636 RETVAL_STRING(sql);
1637 sqlite3_free(sql);
1638 #else
1639 php_sqlite3_error(stmt_obj->db_obj, 0, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
1640 RETURN_FALSE;
1641 #endif
1642 } else {
1643 const char *sql = sqlite3_sql(stmt_obj->stmt);
1644 RETVAL_STRING(sql);
1645 }
1646 }
1647 /* }}} */
1648
1649
register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param * param,php_sqlite3_stmt * stmt)1650 static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
1651 {
1652 HashTable *hash;
1653 hash = stmt->bound_params;
1654
1655 if (!hash) {
1656 ALLOC_HASHTABLE(hash);
1657 zend_hash_init(hash, 13, NULL, sqlite3_param_dtor, 0);
1658 stmt->bound_params = hash;
1659 }
1660
1661 /* We need a : prefix to resolve a name to a parameter number */
1662 if (param->name) {
1663 if (ZSTR_VAL(param->name)[0] != ':' && ZSTR_VAL(param->name)[0] != '@') {
1664 /* pre-increment for character + 1 for null */
1665 zend_string *temp = zend_string_alloc(ZSTR_LEN(param->name) + 1, 0);
1666 ZSTR_VAL(temp)[0] = ':';
1667 memmove(ZSTR_VAL(temp) + 1, ZSTR_VAL(param->name), ZSTR_LEN(param->name) + 1);
1668 param->name = temp;
1669 } else {
1670 param->name = zend_string_copy(param->name);
1671 }
1672 /* do lookup*/
1673 param->param_number = sqlite3_bind_parameter_index(stmt->stmt, ZSTR_VAL(param->name));
1674 }
1675
1676 if (param->param_number < 1) {
1677 if (param->name) {
1678 zend_string_release_ex(param->name, 0);
1679 }
1680 return 0;
1681 }
1682
1683 zend_hash_index_del(hash, param->param_number);
1684
1685 if (param->name) {
1686 zend_hash_update_mem(hash, param->name, param, sizeof(struct php_sqlite3_bound_param));
1687 } else {
1688 zend_hash_index_update_mem(hash, param->param_number, param, sizeof(struct php_sqlite3_bound_param));
1689 }
1690
1691 return 1;
1692 }
1693 /* }}} */
1694
1695 /* {{{ Best try to map between PHP and SQLite. Default is still text. */
1696 #define PHP_SQLITE3_SET_TYPE(z, p) \
1697 switch (Z_TYPE_P(z)) { \
1698 default: \
1699 (p).type = SQLITE_TEXT; \
1700 break; \
1701 case IS_LONG: \
1702 case IS_TRUE: \
1703 case IS_FALSE: \
1704 (p).type = SQLITE_INTEGER; \
1705 break; \
1706 case IS_DOUBLE: \
1707 (p).type = SQLITE_FLOAT; \
1708 break; \
1709 case IS_NULL: \
1710 (p).type = SQLITE_NULL; \
1711 break; \
1712 }
1713 /* }}} */
1714
1715 /* {{{ Common implementation of ::bindParam() and ::bindValue */
sqlite3stmt_bind(INTERNAL_FUNCTION_PARAMETERS)1716 static void sqlite3stmt_bind(INTERNAL_FUNCTION_PARAMETERS)
1717 {
1718 php_sqlite3_stmt *stmt_obj;
1719 zval *object = ZEND_THIS;
1720 struct php_sqlite3_bound_param param = {0};
1721 zval *parameter;
1722 stmt_obj = Z_SQLITE3_STMT_P(object);
1723
1724 param.param_number = -1;
1725 param.type = SQLITE3_TEXT;
1726
1727 ZEND_PARSE_PARAMETERS_START(2, 3)
1728 Z_PARAM_STR_OR_LONG(param.name, param.param_number)
1729 Z_PARAM_ZVAL(parameter)
1730 Z_PARAM_OPTIONAL
1731 Z_PARAM_LONG(param.type)
1732 ZEND_PARSE_PARAMETERS_END();
1733
1734 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1735 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1736
1737 ZVAL_COPY(¶m.parameter, parameter);
1738
1739 if (ZEND_NUM_ARGS() < 3) {
1740 PHP_SQLITE3_SET_TYPE(parameter, param);
1741 }
1742
1743 if (!register_bound_parameter_to_sqlite(¶m, stmt_obj)) {
1744 if (!Z_ISUNDEF(param.parameter)) {
1745 zval_ptr_dtor(&(param.parameter));
1746 ZVAL_UNDEF(¶m.parameter);
1747 }
1748 RETURN_FALSE;
1749 }
1750 RETURN_TRUE;
1751 }
1752 /* }}} */
1753
1754 /* {{{ Bind Parameter to a stmt variable. */
PHP_METHOD(SQLite3Stmt,bindParam)1755 PHP_METHOD(SQLite3Stmt, bindParam)
1756 {
1757 sqlite3stmt_bind(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1758 }
1759 /* }}} */
1760
1761 /* {{{ Bind Value of a parameter to a stmt variable. */
PHP_METHOD(SQLite3Stmt,bindValue)1762 PHP_METHOD(SQLite3Stmt, bindValue)
1763 {
1764 sqlite3stmt_bind(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1765 }
1766 /* }}} */
1767
1768 #undef PHP_SQLITE3_SET_TYPE
1769
1770 /* {{{ Executes a prepared statement and returns a result set object. */
PHP_METHOD(SQLite3Stmt,execute)1771 PHP_METHOD(SQLite3Stmt, execute)
1772 {
1773 php_sqlite3_stmt *stmt_obj;
1774 php_sqlite3_result *result;
1775 zval *object = ZEND_THIS;
1776 int return_code = 0;
1777 int bind_rc = 0;
1778
1779 stmt_obj = Z_SQLITE3_STMT_P(object);
1780
1781 ZEND_PARSE_PARAMETERS_NONE();
1782
1783 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1784
1785 /* Always reset statement before execution, see bug #77051 */
1786 sqlite3_reset(stmt_obj->stmt);
1787
1788 /* Bind parameters to the statement */
1789 bind_rc = php_sqlite3_bind_params(stmt_obj);
1790
1791 if (bind_rc == FAILURE || EG(exception)) {
1792 RETURN_FALSE;
1793 }
1794
1795 return_code = sqlite3_step(stmt_obj->stmt);
1796
1797 switch (return_code) {
1798 case SQLITE_ROW: /* Valid Row */
1799 case SQLITE_DONE: /* Valid but no results */
1800 {
1801 sqlite3_reset(stmt_obj->stmt);
1802 object_init_ex(return_value, php_sqlite3_result_entry);
1803 result = Z_SQLITE3_RESULT_P(return_value);
1804
1805 result->is_prepared_statement = 1;
1806 result->db_obj = stmt_obj->db_obj;
1807 result->stmt_obj = stmt_obj;
1808 result->column_names = NULL;
1809 result->column_count = -1;
1810 ZVAL_OBJ_COPY(&result->stmt_obj_zval, Z_OBJ_P(object));
1811
1812 break;
1813 }
1814 case SQLITE_ERROR:
1815 sqlite3_reset(stmt_obj->stmt);
1816 ZEND_FALLTHROUGH;
1817 default:
1818 if (!EG(exception)) {
1819 php_sqlite3_error(stmt_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(stmt_obj->stmt)));
1820 }
1821 zval_ptr_dtor(return_value);
1822 RETURN_FALSE;
1823 }
1824
1825 return;
1826 }
1827 /* }}} */
1828
1829 /* {{{ __constructor for SQLite3Stmt. */
PHP_METHOD(SQLite3Stmt,__construct)1830 PHP_METHOD(SQLite3Stmt, __construct)
1831 {
1832 php_sqlite3_stmt *stmt_obj;
1833 php_sqlite3_db_object *db_obj;
1834 zval *object = ZEND_THIS;
1835 zval *db_zval;
1836 zend_string *sql;
1837 int errcode;
1838 php_sqlite3_free_list *free_item;
1839
1840 stmt_obj = Z_SQLITE3_STMT_P(object);
1841
1842 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &db_zval, php_sqlite3_sc_entry, &sql) == FAILURE) {
1843 RETURN_THROWS();
1844 }
1845
1846 db_obj = Z_SQLITE3_DB_P(db_zval);
1847
1848 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1849
1850 if (!ZSTR_LEN(sql)) {
1851 RETURN_FALSE;
1852 }
1853
1854 stmt_obj->db_obj = db_obj;
1855 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(db_zval));
1856
1857 errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
1858 if (errcode != SQLITE_OK) {
1859 php_sqlite3_error(db_obj, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
1860 zval_ptr_dtor(return_value);
1861 RETURN_FALSE;
1862 }
1863 stmt_obj->initialised = 1;
1864
1865 free_item = emalloc(sizeof(php_sqlite3_free_list));
1866 free_item->stmt_obj = stmt_obj;
1867 //?? free_item->stmt_obj_zval = ZEND_THIS;
1868 ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(object));
1869
1870 zend_llist_add_element(&(db_obj->free_list), &free_item);
1871 }
1872 /* }}} */
1873
1874 /* {{{ Number of columns in the result set. */
PHP_METHOD(SQLite3Result,numColumns)1875 PHP_METHOD(SQLite3Result, numColumns)
1876 {
1877 php_sqlite3_result *result_obj;
1878 zval *object = ZEND_THIS;
1879 result_obj = Z_SQLITE3_RESULT_P(object);
1880
1881 ZEND_PARSE_PARAMETERS_NONE();
1882
1883 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1884
1885 RETURN_LONG(sqlite3_column_count(result_obj->stmt_obj->stmt));
1886 }
1887 /* }}} */
1888
1889 /* {{{ Returns the name of the nth column. */
PHP_METHOD(SQLite3Result,columnName)1890 PHP_METHOD(SQLite3Result, columnName)
1891 {
1892 php_sqlite3_result *result_obj;
1893 zval *object = ZEND_THIS;
1894 zend_long column = 0;
1895 char *column_name;
1896 result_obj = Z_SQLITE3_RESULT_P(object);
1897
1898 ZEND_PARSE_PARAMETERS_START(1, 1)
1899 Z_PARAM_LONG(column)
1900 ZEND_PARSE_PARAMETERS_END();
1901
1902 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1903
1904 column_name = (char*) sqlite3_column_name(result_obj->stmt_obj->stmt, column);
1905
1906 if (column_name == NULL) {
1907 RETURN_FALSE;
1908 }
1909
1910 RETVAL_STRING(column_name);
1911 }
1912 /* }}} */
1913
1914 /* {{{ Returns the type of the nth column. */
PHP_METHOD(SQLite3Result,columnType)1915 PHP_METHOD(SQLite3Result, columnType)
1916 {
1917 php_sqlite3_result *result_obj;
1918 zval *object = ZEND_THIS;
1919 zend_long column = 0;
1920 result_obj = Z_SQLITE3_RESULT_P(object);
1921
1922 ZEND_PARSE_PARAMETERS_START(1, 1)
1923 Z_PARAM_LONG(column)
1924 ZEND_PARSE_PARAMETERS_END();
1925
1926 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1927
1928 if (!sqlite3_data_count(result_obj->stmt_obj->stmt)) {
1929 RETURN_FALSE;
1930 }
1931
1932 RETURN_LONG(sqlite3_column_type(result_obj->stmt_obj->stmt, column));
1933 }
1934 /* }}} */
1935
1936 /* {{{ Fetch a result row as both an associative or numerically indexed array or both. */
PHP_METHOD(SQLite3Result,fetchArray)1937 PHP_METHOD(SQLite3Result, fetchArray)
1938 {
1939 php_sqlite3_result *result_obj;
1940 zval *object = ZEND_THIS;
1941 int i, ret;
1942 zend_long mode = PHP_SQLITE3_BOTH;
1943 result_obj = Z_SQLITE3_RESULT_P(object);
1944
1945 ZEND_PARSE_PARAMETERS_START(0, 1)
1946 Z_PARAM_OPTIONAL
1947 Z_PARAM_LONG(mode)
1948 ZEND_PARSE_PARAMETERS_END();
1949
1950 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1951
1952 ret = sqlite3_step(result_obj->stmt_obj->stmt);
1953 switch (ret) {
1954 case SQLITE_ROW:
1955 /* If there was no return value then just skip fetching */
1956 if (!USED_RET()) {
1957 RETURN_FALSE;
1958 }
1959
1960 if (result_obj->column_count == -1) {
1961 result_obj->column_count = sqlite3_column_count(result_obj->stmt_obj->stmt);
1962 }
1963
1964 int n_cols = result_obj->column_count;
1965
1966 /* Cache column names to speed up repeated fetchArray calls. */
1967 if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) {
1968 result_obj->column_names = emalloc(n_cols * sizeof(zend_string*));
1969
1970 for (int i = 0; i < n_cols; i++) {
1971 const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);
1972 result_obj->column_names[i] = zend_string_init(column, strlen(column), 0);
1973 }
1974 }
1975
1976 array_init(return_value);
1977
1978 for (i = 0; i < n_cols; i++) {
1979 zval data;
1980
1981 sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data);
1982
1983 if (mode & PHP_SQLITE3_NUM) {
1984 add_index_zval(return_value, i, &data);
1985 }
1986
1987 if (mode & PHP_SQLITE3_ASSOC) {
1988 if (mode & PHP_SQLITE3_NUM) {
1989 if (Z_REFCOUNTED(data)) {
1990 Z_ADDREF(data);
1991 }
1992 }
1993 /* Note: we can't use the "add_new" variant here instead of "update" because
1994 * when the same column name is encountered, the last result should be taken. */
1995 zend_symtable_update(Z_ARR_P(return_value), result_obj->column_names[i], &data);
1996 }
1997 }
1998 break;
1999
2000 case SQLITE_DONE:
2001 RETURN_FALSE;
2002 break;
2003
2004 default:
2005 php_sqlite3_error(result_obj->db_obj, sqlite3_errcode(sqlite3_db_handle(result_obj->stmt_obj->stmt)), "Unable to execute statement: %s", sqlite3_errmsg(sqlite3_db_handle(result_obj->stmt_obj->stmt)));
2006 }
2007 }
2008 /* }}} */
2009
sqlite3result_clear_column_names_cache(php_sqlite3_result * result)2010 static void sqlite3result_clear_column_names_cache(php_sqlite3_result *result) {
2011 if (result->column_names) {
2012 for (int i = 0; i < result->column_count; i++) {
2013 zend_string_release(result->column_names[i]);
2014 }
2015 efree(result->column_names);
2016 }
2017 result->column_names = NULL;
2018 result->column_count = -1;
2019 }
2020
2021 /* {{{ Resets the result set back to the first row. */
PHP_METHOD(SQLite3Result,reset)2022 PHP_METHOD(SQLite3Result, reset)
2023 {
2024 php_sqlite3_result *result_obj;
2025 zval *object = ZEND_THIS;
2026 result_obj = Z_SQLITE3_RESULT_P(object);
2027
2028 ZEND_PARSE_PARAMETERS_NONE();
2029
2030 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
2031
2032 sqlite3result_clear_column_names_cache(result_obj);
2033
2034 if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) {
2035 RETURN_FALSE;
2036 }
2037
2038 RETURN_TRUE;
2039 }
2040 /* }}} */
2041
2042 /* {{{ Closes the result set. */
PHP_METHOD(SQLite3Result,finalize)2043 PHP_METHOD(SQLite3Result, finalize)
2044 {
2045 php_sqlite3_result *result_obj;
2046 zval *object = ZEND_THIS;
2047 result_obj = Z_SQLITE3_RESULT_P(object);
2048
2049 ZEND_PARSE_PARAMETERS_NONE();
2050
2051 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
2052
2053 sqlite3result_clear_column_names_cache(result_obj);
2054
2055 /* We need to finalize an internal statement */
2056 if (result_obj->is_prepared_statement == 0) {
2057 zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj_zval,
2058 (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
2059 } else {
2060 sqlite3_reset(result_obj->stmt_obj->stmt);
2061 }
2062
2063 RETURN_TRUE;
2064 }
2065 /* }}} */
2066
2067 /* {{{ __constructor for SQLite3Result. */
PHP_METHOD(SQLite3Result,__construct)2068 PHP_METHOD(SQLite3Result, __construct)
2069 {
2070 zend_throw_exception(zend_ce_exception, "SQLite3Result cannot be directly instantiated", 0);
2071 }
2072 /* }}} */
2073
2074 /* {{{ Authorization Callback */
php_sqlite3_authorizer(void * autharg,int action,const char * arg1,const char * arg2,const char * arg3,const char * arg4)2075 static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4)
2076 {
2077 /* Check open_basedir restrictions first */
2078 if (PG(open_basedir) && *PG(open_basedir)) {
2079 if (action == SQLITE_ATTACH) {
2080 if (!arg1) {
2081 return SQLITE_DENY;
2082 }
2083 if (memcmp(arg1, ":memory:", sizeof(":memory:")) && *arg1) {
2084 if (strncmp(arg1, "file:", 5) == 0) {
2085 /* starts with "file:" */
2086 return SQLITE_DENY;
2087 } else if (php_check_open_basedir(arg1)) {
2088 return SQLITE_DENY;
2089 }
2090 }
2091 }
2092 }
2093
2094 php_sqlite3_db_object *db_obj = (php_sqlite3_db_object *)autharg;
2095
2096 /* fallback to access allowed if authorizer callback is not defined */
2097 if (!ZEND_FCC_INITIALIZED(db_obj->authorizer_fcc)) {
2098 return SQLITE_OK;
2099 }
2100
2101 /* call userland authorizer callback, if set */
2102 zval retval;
2103 zval argv[5];
2104
2105 ZVAL_LONG(&argv[0], action);
2106
2107 if (NULL == arg1) {
2108 ZVAL_NULL(&argv[1]);
2109 } else {
2110 ZVAL_STRING(&argv[1], arg1);
2111 }
2112
2113 if (NULL == arg2) {
2114 ZVAL_NULL(&argv[2]);
2115 } else {
2116 ZVAL_STRING(&argv[2], arg2);
2117 }
2118
2119 if (NULL == arg3) {
2120 ZVAL_NULL(&argv[3]);
2121 } else {
2122 ZVAL_STRING(&argv[3], arg3);
2123 }
2124
2125 if (NULL == arg4) {
2126 ZVAL_NULL(&argv[4]);
2127 } else {
2128 ZVAL_STRING(&argv[4], arg4);
2129 }
2130
2131 int authreturn = SQLITE_DENY;
2132
2133 zend_call_known_fcc(&db_obj->authorizer_fcc, &retval, /* argc */ 5, argv, /* named_params */ NULL);
2134 if (Z_ISUNDEF(retval)) {
2135 php_sqlite3_error(db_obj, 0, "An error occurred while invoking the authorizer callback");
2136 } else {
2137 if (Z_TYPE(retval) != IS_LONG) {
2138 php_sqlite3_error(db_obj, 0, "The authorizer callback returned an invalid type: expected int");
2139 } else {
2140 authreturn = Z_LVAL(retval);
2141
2142 if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY) {
2143 php_sqlite3_error(db_obj, 0, "The authorizer callback returned an invalid value: %d", authreturn);
2144 authreturn = SQLITE_DENY;
2145 }
2146 }
2147 }
2148
2149 /* Free local return and argument values */
2150 zval_ptr_dtor(&retval);
2151 zval_ptr_dtor(&argv[0]);
2152 zval_ptr_dtor(&argv[1]);
2153 zval_ptr_dtor(&argv[2]);
2154 zval_ptr_dtor(&argv[3]);
2155 zval_ptr_dtor(&argv[4]);
2156
2157 return authreturn;
2158 }
2159 /* }}} */
2160
2161 /* {{{ php_sqlite3_free_list_dtor */
php_sqlite3_free_list_dtor(void ** item)2162 static void php_sqlite3_free_list_dtor(void **item)
2163 {
2164 php_sqlite3_free_list *free_item = (php_sqlite3_free_list *)*item;
2165
2166 if (free_item->stmt_obj && free_item->stmt_obj->initialised) {
2167 sqlite3_finalize(free_item->stmt_obj->stmt);
2168 free_item->stmt_obj->initialised = 0;
2169 }
2170 efree(*item);
2171 }
2172 /* }}} */
2173
php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list ** free_list,zval * statement)2174 static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
2175 {
2176 return ((*free_list)->stmt_obj->initialised && Z_PTR_P(statement) == Z_PTR((*free_list)->stmt_obj_zval));
2177 }
2178 /* }}} */
2179
php_sqlite3_compare_stmt_free(php_sqlite3_free_list ** free_list,sqlite3_stmt * statement)2180 static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sqlite3_stmt *statement ) /* {{{ */
2181 {
2182 return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt);
2183 }
2184 /* }}} */
2185
php_sqlite3_object_free_storage(zend_object * object)2186 static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */
2187 {
2188 php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
2189 php_sqlite3_func *func;
2190 php_sqlite3_collation *collation;
2191
2192 if (!intern) {
2193 return;
2194 }
2195
2196 /* Release function_name from authorizer */
2197 if (ZEND_FCC_INITIALIZED(intern->authorizer_fcc)) {
2198 zend_fcc_dtor(&intern->authorizer_fcc);
2199 }
2200
2201 while (intern->funcs) {
2202 func = intern->funcs;
2203 intern->funcs = func->next;
2204 if (intern->initialised && intern->db) {
2205 sqlite3_create_function(intern->db, func->func_name, func->argc, SQLITE_UTF8, func, NULL, NULL, NULL);
2206 }
2207
2208 efree((char*)func->func_name);
2209
2210 if (ZEND_FCC_INITIALIZED(func->func)) {
2211 zend_fcc_dtor(&func->func);
2212 }
2213 if (ZEND_FCC_INITIALIZED(func->step)) {
2214 zend_fcc_dtor(&func->step);
2215 }
2216 if (ZEND_FCC_INITIALIZED(func->fini)) {
2217 zend_fcc_dtor(&func->fini);
2218 }
2219 efree(func);
2220 }
2221
2222 while (intern->collations){
2223 collation = intern->collations;
2224 intern->collations = collation->next;
2225 if (intern->initialised && intern->db){
2226 sqlite3_create_collation(intern->db, collation->collation_name, SQLITE_UTF8, NULL, NULL);
2227 }
2228 efree((char*)collation->collation_name);
2229 if (ZEND_FCC_INITIALIZED(collation->cmp_func)) {
2230 zend_fcc_dtor(&collation->cmp_func);
2231 }
2232 efree(collation);
2233 }
2234
2235 if (intern->initialised && intern->db) {
2236 sqlite3_close(intern->db);
2237 intern->initialised = 0;
2238 }
2239
2240 zend_object_std_dtor(&intern->zo);
2241 }
2242 /* }}} */
2243
php_sqlite3_gc_buffer_add_fcc(zend_get_gc_buffer * gc_buffer,zend_fcall_info_cache * fcc)2244 static void php_sqlite3_gc_buffer_add_fcc(zend_get_gc_buffer *gc_buffer, zend_fcall_info_cache *fcc)
2245 {
2246 if (ZEND_FCC_INITIALIZED(*fcc)) {
2247 zend_get_gc_buffer_add_fcc(gc_buffer, fcc);
2248 }
2249 }
2250
php_sqlite3_get_gc(zend_object * object,zval ** table,int * n)2251 static HashTable *php_sqlite3_get_gc(zend_object *object, zval **table, int *n)
2252 {
2253 php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
2254
2255 if (intern->funcs == NULL && intern->collations == NULL) {
2256 /* Fast path without allocations */
2257 *table = NULL;
2258 *n = 0;
2259 return zend_std_get_gc(object, table, n);
2260 } else {
2261 zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
2262
2263 php_sqlite3_func *func = intern->funcs;
2264 while (func != NULL) {
2265 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &func->func);
2266 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &func->step);
2267 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &func->fini);
2268 func = func->next;
2269 }
2270
2271 php_sqlite3_collation *collation = intern->collations;
2272 while (collation != NULL) {
2273 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &collation->cmp_func);
2274 collation = collation->next;
2275 }
2276
2277 zend_get_gc_buffer_use(gc_buffer, table, n);
2278
2279 if (object->properties == NULL && object->ce->default_properties_count == 0) {
2280 return NULL;
2281 } else {
2282 return zend_std_get_properties(object);
2283 }
2284 }
2285 }
2286
php_sqlite3_stmt_object_free_storage(zend_object * object)2287 static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */
2288 {
2289 php_sqlite3_stmt *intern = php_sqlite3_stmt_from_obj(object);
2290
2291 if (!intern) {
2292 return;
2293 }
2294
2295 if (intern->bound_params) {
2296 zend_hash_destroy(intern->bound_params);
2297 FREE_HASHTABLE(intern->bound_params);
2298 intern->bound_params = NULL;
2299 }
2300
2301 if (intern->initialised) {
2302 zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt,
2303 (int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
2304 }
2305
2306 if (!Z_ISUNDEF(intern->db_obj_zval)) {
2307 zval_ptr_dtor(&intern->db_obj_zval);
2308 }
2309
2310 zend_object_std_dtor(&intern->zo);
2311 }
2312 /* }}} */
2313
php_sqlite3_result_object_free_storage(zend_object * object)2314 static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ */
2315 {
2316 php_sqlite3_result *intern = php_sqlite3_result_from_obj(object);
2317
2318 if (!intern) {
2319 return;
2320 }
2321
2322 sqlite3result_clear_column_names_cache(intern);
2323
2324 if (!Z_ISNULL(intern->stmt_obj_zval)) {
2325 if (intern->stmt_obj && intern->stmt_obj->initialised) {
2326 sqlite3_reset(intern->stmt_obj->stmt);
2327 }
2328
2329 zval_ptr_dtor(&intern->stmt_obj_zval);
2330 }
2331
2332 zend_object_std_dtor(&intern->zo);
2333 }
2334 /* }}} */
2335
php_sqlite3_object_new(zend_class_entry * class_type)2336 static zend_object *php_sqlite3_object_new(zend_class_entry *class_type) /* {{{ */
2337 {
2338 php_sqlite3_db_object *intern;
2339
2340 /* Allocate memory for it */
2341 intern = zend_object_alloc(sizeof(php_sqlite3_db_object), class_type);
2342
2343 /* Need to keep track of things to free */
2344 zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
2345
2346 zend_object_std_init(&intern->zo, class_type);
2347 object_properties_init(&intern->zo, class_type);
2348
2349 return &intern->zo;
2350 }
2351 /* }}} */
2352
php_sqlite3_stmt_object_new(zend_class_entry * class_type)2353 static zend_object *php_sqlite3_stmt_object_new(zend_class_entry *class_type) /* {{{ */
2354 {
2355 php_sqlite3_stmt *intern;
2356
2357 /* Allocate memory for it */
2358 intern = zend_object_alloc(sizeof(php_sqlite3_stmt), class_type);
2359
2360 zend_object_std_init(&intern->zo, class_type);
2361 object_properties_init(&intern->zo, class_type);
2362
2363 return &intern->zo;
2364 }
2365 /* }}} */
2366
php_sqlite3_result_object_new(zend_class_entry * class_type)2367 static zend_object *php_sqlite3_result_object_new(zend_class_entry *class_type) /* {{{ */
2368 {
2369 php_sqlite3_result *intern;
2370
2371 /* Allocate memory for it */
2372 intern = zend_object_alloc(sizeof(php_sqlite3_result), class_type);
2373
2374 zend_object_std_init(&intern->zo, class_type);
2375 object_properties_init(&intern->zo, class_type);
2376
2377 return &intern->zo;
2378 }
2379 /* }}} */
2380
sqlite3_param_dtor(zval * data)2381 static void sqlite3_param_dtor(zval *data) /* {{{ */
2382 {
2383 struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)Z_PTR_P(data);
2384
2385 if (param->name) {
2386 zend_string_release_ex(param->name, 0);
2387 }
2388
2389 if (!Z_ISNULL(param->parameter)) {
2390 zval_ptr_dtor(&(param->parameter));
2391 ZVAL_UNDEF(¶m->parameter);
2392 }
2393 efree(param);
2394 }
2395 /* }}} */
2396
2397 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(sqlite3)2398 PHP_MINIT_FUNCTION(sqlite3)
2399 {
2400 /* Register SQLite3Exception class */
2401 php_sqlite3_exception_ce = register_class_SQLite3Exception(zend_ce_exception);
2402
2403 #ifdef ZTS
2404 /* Refuse to load if this wasn't a threasafe library loaded */
2405 if (!sqlite3_threadsafe()) {
2406 php_error_docref(NULL, E_WARNING, "A thread safe version of SQLite is required when using a thread safe version of PHP.");
2407 return FAILURE;
2408 }
2409 #endif
2410
2411 memcpy(&sqlite3_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2412 memcpy(&sqlite3_stmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2413 memcpy(&sqlite3_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2414
2415 /* Register SQLite 3 Class */
2416 sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo);
2417 sqlite3_object_handlers.clone_obj = NULL;
2418 sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage;
2419 sqlite3_object_handlers.get_gc = php_sqlite3_get_gc;
2420 php_sqlite3_sc_entry = register_class_SQLite3();
2421 php_sqlite3_sc_entry->create_object = php_sqlite3_object_new;
2422 php_sqlite3_sc_entry->default_object_handlers = &sqlite3_object_handlers;
2423
2424 /* Register SQLite 3 Prepared Statement Class */
2425 sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo);
2426 sqlite3_stmt_object_handlers.clone_obj = NULL;
2427 sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage;
2428 php_sqlite3_stmt_entry = register_class_SQLite3Stmt();
2429 php_sqlite3_stmt_entry->create_object = php_sqlite3_stmt_object_new;
2430 php_sqlite3_stmt_entry->default_object_handlers = &sqlite3_stmt_object_handlers;
2431
2432 /* Register SQLite 3 Result Class */
2433 sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo);
2434 sqlite3_result_object_handlers.clone_obj = NULL;
2435 sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage;
2436 php_sqlite3_result_entry = register_class_SQLite3Result();
2437 php_sqlite3_result_entry->create_object = php_sqlite3_result_object_new;
2438 php_sqlite3_result_entry->default_object_handlers = &sqlite3_result_object_handlers;
2439
2440 REGISTER_INI_ENTRIES();
2441
2442 register_sqlite3_symbols(module_number);
2443
2444 return SUCCESS;
2445 }
2446 /* }}} */
2447
2448 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(sqlite3)2449 PHP_MSHUTDOWN_FUNCTION(sqlite3)
2450 {
2451 UNREGISTER_INI_ENTRIES();
2452
2453 return SUCCESS;
2454 }
2455 /* }}} */
2456
2457 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(sqlite3)2458 PHP_MINFO_FUNCTION(sqlite3)
2459 {
2460 php_info_print_table_start();
2461 php_info_print_table_row(2, "SQLite3 support", "enabled");
2462 php_info_print_table_row(2, "SQLite Library", sqlite3_libversion());
2463 php_info_print_table_end();
2464
2465 DISPLAY_INI_ENTRIES();
2466 }
2467 /* }}} */
2468
2469 /* {{{ PHP_GINIT_FUNCTION */
PHP_GINIT_FUNCTION(sqlite3)2470 static PHP_GINIT_FUNCTION(sqlite3)
2471 {
2472 #if defined(COMPILE_DL_SQLITE3) && defined(ZTS)
2473 ZEND_TSRMLS_CACHE_UPDATE();
2474 #endif
2475 memset(sqlite3_globals, 0, sizeof(*sqlite3_globals));
2476 }
2477 /* }}} */
2478
2479 /* {{{ sqlite3_module_entry */
2480 zend_module_entry sqlite3_module_entry = {
2481 STANDARD_MODULE_HEADER,
2482 "sqlite3",
2483 NULL,
2484 PHP_MINIT(sqlite3),
2485 PHP_MSHUTDOWN(sqlite3),
2486 NULL,
2487 NULL,
2488 PHP_MINFO(sqlite3),
2489 PHP_SQLITE3_VERSION,
2490 PHP_MODULE_GLOBALS(sqlite3),
2491 PHP_GINIT(sqlite3),
2492 NULL,
2493 NULL,
2494 STANDARD_MODULE_PROPERTIES_EX
2495 };
2496 /* }}} */
2497
2498 #ifdef COMPILE_DL_SQLITE3
2499 #ifdef ZTS
2500 ZEND_TSRMLS_CACHE_DEFINE()
2501 #endif
2502 ZEND_GET_MODULE(sqlite3)
2503 #endif
2504