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_FALSE;
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 if(stmt_obj->db_obj) {
1431 zend_llist_del_element(&(stmt_obj->db_obj->free_list), object, (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
1432 }
1433
1434 RETURN_TRUE;
1435 }
1436 /* }}} */
1437
1438 /* {{{ Reset the prepared statement to the state before it was executed, bindings still remain. */
PHP_METHOD(SQLite3Stmt,reset)1439 PHP_METHOD(SQLite3Stmt, reset)
1440 {
1441 php_sqlite3_stmt *stmt_obj;
1442 zval *object = ZEND_THIS;
1443 stmt_obj = Z_SQLITE3_STMT_P(object);
1444
1445 ZEND_PARSE_PARAMETERS_NONE();
1446
1447 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1448 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1449
1450 if (sqlite3_reset(stmt_obj->stmt) != SQLITE_OK) {
1451 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)));
1452 RETURN_FALSE;
1453 }
1454 RETURN_TRUE;
1455 }
1456 /* }}} */
1457
1458 /* {{{ Clear all current bound parameters. */
PHP_METHOD(SQLite3Stmt,clear)1459 PHP_METHOD(SQLite3Stmt, clear)
1460 {
1461 php_sqlite3_stmt *stmt_obj;
1462 zval *object = ZEND_THIS;
1463 stmt_obj = Z_SQLITE3_STMT_P(object);
1464
1465 ZEND_PARSE_PARAMETERS_NONE();
1466
1467 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1468 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1469
1470 if (sqlite3_clear_bindings(stmt_obj->stmt) != SQLITE_OK) {
1471 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)));
1472 RETURN_FALSE;
1473 }
1474
1475 if (stmt_obj->bound_params) {
1476 zend_hash_destroy(stmt_obj->bound_params);
1477 FREE_HASHTABLE(stmt_obj->bound_params);
1478 stmt_obj->bound_params = NULL;
1479 }
1480
1481 RETURN_TRUE;
1482 }
1483 /* }}} */
1484
1485 /* {{{ Returns true if a statement is definitely read only */
PHP_METHOD(SQLite3Stmt,readOnly)1486 PHP_METHOD(SQLite3Stmt, readOnly)
1487 {
1488 php_sqlite3_stmt *stmt_obj;
1489 zval *object = ZEND_THIS;
1490 stmt_obj = Z_SQLITE3_STMT_P(object);
1491
1492 ZEND_PARSE_PARAMETERS_NONE();
1493
1494 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1495 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1496
1497 if (sqlite3_stmt_readonly(stmt_obj->stmt)) {
1498 RETURN_TRUE;
1499 }
1500 RETURN_FALSE;
1501 }
1502 /* }}} */
1503
1504 /* bind parameters to a statement before execution */
php_sqlite3_bind_params(php_sqlite3_stmt * stmt_obj)1505 static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
1506 {
1507 struct php_sqlite3_bound_param *param;
1508 int return_code;
1509
1510 if (stmt_obj->bound_params) {
1511 ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) {
1512 zval *parameter;
1513 /* parameter must be a reference? */
1514 if (Z_ISREF(param->parameter)) {
1515 parameter = Z_REFVAL(param->parameter);
1516 } else {
1517 parameter = ¶m->parameter;
1518 }
1519
1520 /* If the ZVAL is null then it should be bound as that */
1521 if (Z_TYPE_P(parameter) == IS_NULL) {
1522 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1523 if (return_code != SQLITE_OK) {
1524 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1525 }
1526 continue;
1527 }
1528
1529 switch (param->type) {
1530 case SQLITE_INTEGER:
1531 convert_to_long(parameter);
1532 #if ZEND_LONG_MAX > 2147483647
1533 return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
1534 #else
1535 return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter));
1536 #endif
1537 if (return_code != SQLITE_OK) {
1538 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1539 }
1540 break;
1541
1542 case SQLITE_FLOAT:
1543 convert_to_double(parameter);
1544 return_code = sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter));
1545 if (return_code != SQLITE_OK) {
1546 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1547 }
1548 break;
1549
1550 case SQLITE_BLOB:
1551 {
1552 php_stream *stream = NULL;
1553 zend_string *buffer = NULL;
1554 if (Z_TYPE_P(parameter) == IS_RESOURCE) {
1555 php_stream_from_zval_no_verify(stream, parameter);
1556 if (stream == NULL) {
1557 php_sqlite3_error(stmt_obj->db_obj, 0, "Unable to read stream for parameter %ld", param->param_number);
1558 return FAILURE;
1559 }
1560 buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
1561 } else {
1562 buffer = zval_get_string(parameter);
1563 }
1564
1565 if (buffer) {
1566 return_code = sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT);
1567 zend_string_release_ex(buffer, 0);
1568 if (return_code != SQLITE_OK) {
1569 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1570 }
1571 } else {
1572 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1573 if (return_code != SQLITE_OK) {
1574 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1575 }
1576 }
1577 break;
1578 }
1579
1580 case SQLITE3_TEXT: {
1581 zend_string *str = zval_try_get_string(parameter);
1582 if (UNEXPECTED(!str)) {
1583 return FAILURE;
1584 }
1585 return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, ZSTR_VAL(str), ZSTR_LEN(str), SQLITE_TRANSIENT);
1586 if (return_code != SQLITE_OK) {
1587 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1588 }
1589 zend_string_release(str);
1590 break;
1591 }
1592
1593 case SQLITE_NULL:
1594 return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number);
1595 if (return_code != SQLITE_OK) {
1596 php_sqlite3_error(stmt_obj->db_obj, return_code, "Unable to bind parameter number " ZEND_LONG_FMT, param->param_number);
1597 }
1598 break;
1599
1600 default:
1601 php_sqlite3_error(stmt_obj->db_obj, 0, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number);
1602 return FAILURE;
1603 }
1604 } ZEND_HASH_FOREACH_END();
1605 }
1606
1607 return SUCCESS;
1608 }
1609 /* }}} */
1610
1611
1612 /* {{{ Returns the SQL statement used to prepare the query. If expanded is true, binded parameters and values will be expanded. */
PHP_METHOD(SQLite3Stmt,getSQL)1613 PHP_METHOD(SQLite3Stmt, getSQL)
1614 {
1615 php_sqlite3_stmt *stmt_obj;
1616 bool expanded = 0;
1617 zval *object = getThis();
1618 stmt_obj = Z_SQLITE3_STMT_P(object);
1619 int bind_rc;
1620
1621 ZEND_PARSE_PARAMETERS_START(0, 1)
1622 Z_PARAM_OPTIONAL
1623 Z_PARAM_BOOL(expanded)
1624 ZEND_PARSE_PARAMETERS_END();
1625
1626 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1627 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1628
1629 bind_rc = php_sqlite3_bind_params(stmt_obj);
1630
1631 if (bind_rc == FAILURE || EG(exception)) {
1632 RETURN_FALSE;
1633 }
1634
1635 if (expanded) {
1636 #ifdef HAVE_SQLITE3_EXPANDED_SQL
1637 char *sql = sqlite3_expanded_sql(stmt_obj->stmt);
1638 RETVAL_STRING(sql);
1639 sqlite3_free(sql);
1640 #else
1641 php_sqlite3_error(stmt_obj->db_obj, 0, "The expanded parameter requires SQLite3 >= 3.14 and %s is installed", sqlite3_libversion());
1642 RETURN_FALSE;
1643 #endif
1644 } else {
1645 const char *sql = sqlite3_sql(stmt_obj->stmt);
1646 RETVAL_STRING(sql);
1647 }
1648 }
1649 /* }}} */
1650
1651
register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param * param,php_sqlite3_stmt * stmt)1652 static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */
1653 {
1654 HashTable *hash;
1655 hash = stmt->bound_params;
1656
1657 if (!hash) {
1658 ALLOC_HASHTABLE(hash);
1659 zend_hash_init(hash, 13, NULL, sqlite3_param_dtor, 0);
1660 stmt->bound_params = hash;
1661 }
1662
1663 /* We need a : prefix to resolve a name to a parameter number */
1664 if (param->name) {
1665 if (ZSTR_VAL(param->name)[0] != ':' && ZSTR_VAL(param->name)[0] != '@') {
1666 /* pre-increment for character + 1 for null */
1667 zend_string *temp = zend_string_alloc(ZSTR_LEN(param->name) + 1, 0);
1668 ZSTR_VAL(temp)[0] = ':';
1669 memmove(ZSTR_VAL(temp) + 1, ZSTR_VAL(param->name), ZSTR_LEN(param->name) + 1);
1670 param->name = temp;
1671 } else {
1672 param->name = zend_string_copy(param->name);
1673 }
1674 /* do lookup*/
1675 param->param_number = sqlite3_bind_parameter_index(stmt->stmt, ZSTR_VAL(param->name));
1676 }
1677
1678 if (param->param_number < 1) {
1679 if (param->name) {
1680 zend_string_release_ex(param->name, 0);
1681 }
1682 return 0;
1683 }
1684
1685 if (param->param_number >= 1) {
1686 zend_hash_index_del(hash, param->param_number);
1687 }
1688
1689 if (param->name) {
1690 zend_hash_update_mem(hash, param->name, param, sizeof(struct php_sqlite3_bound_param));
1691 } else {
1692 zend_hash_index_update_mem(hash, param->param_number, param, sizeof(struct php_sqlite3_bound_param));
1693 }
1694
1695 return 1;
1696 }
1697 /* }}} */
1698
1699 /* {{{ Best try to map between PHP and SQLite. Default is still text. */
1700 #define PHP_SQLITE3_SET_TYPE(z, p) \
1701 switch (Z_TYPE_P(z)) { \
1702 default: \
1703 (p).type = SQLITE_TEXT; \
1704 break; \
1705 case IS_LONG: \
1706 case IS_TRUE: \
1707 case IS_FALSE: \
1708 (p).type = SQLITE_INTEGER; \
1709 break; \
1710 case IS_DOUBLE: \
1711 (p).type = SQLITE_FLOAT; \
1712 break; \
1713 case IS_NULL: \
1714 (p).type = SQLITE_NULL; \
1715 break; \
1716 }
1717 /* }}} */
1718
1719 /* {{{ Common implementation of ::bindParam() and ::bindValue */
sqlite3stmt_bind(INTERNAL_FUNCTION_PARAMETERS)1720 static void sqlite3stmt_bind(INTERNAL_FUNCTION_PARAMETERS)
1721 {
1722 php_sqlite3_stmt *stmt_obj;
1723 zval *object = ZEND_THIS;
1724 struct php_sqlite3_bound_param param = {0};
1725 zval *parameter;
1726 stmt_obj = Z_SQLITE3_STMT_P(object);
1727
1728 param.param_number = -1;
1729 param.type = SQLITE3_TEXT;
1730
1731 ZEND_PARSE_PARAMETERS_START(2, 3)
1732 Z_PARAM_STR_OR_LONG(param.name, param.param_number)
1733 Z_PARAM_ZVAL(parameter)
1734 Z_PARAM_OPTIONAL
1735 Z_PARAM_LONG(param.type)
1736 ZEND_PARSE_PARAMETERS_END();
1737
1738 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1739 SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1740
1741 ZVAL_COPY(¶m.parameter, parameter);
1742
1743 if (ZEND_NUM_ARGS() < 3) {
1744 PHP_SQLITE3_SET_TYPE(parameter, param);
1745 }
1746
1747 if (!register_bound_parameter_to_sqlite(¶m, stmt_obj)) {
1748 if (!Z_ISUNDEF(param.parameter)) {
1749 zval_ptr_dtor(&(param.parameter));
1750 ZVAL_UNDEF(¶m.parameter);
1751 }
1752 RETURN_FALSE;
1753 }
1754 RETURN_TRUE;
1755 }
1756 /* }}} */
1757
1758 /* {{{ Bind Parameter to a stmt variable. */
PHP_METHOD(SQLite3Stmt,bindParam)1759 PHP_METHOD(SQLite3Stmt, bindParam)
1760 {
1761 sqlite3stmt_bind(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1762 }
1763 /* }}} */
1764
1765 /* {{{ Bind Value of a parameter to a stmt variable. */
PHP_METHOD(SQLite3Stmt,bindValue)1766 PHP_METHOD(SQLite3Stmt, bindValue)
1767 {
1768 sqlite3stmt_bind(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1769 }
1770 /* }}} */
1771
1772 #undef PHP_SQLITE3_SET_TYPE
1773
1774 /* {{{ Executes a prepared statement and returns a result set object. */
PHP_METHOD(SQLite3Stmt,execute)1775 PHP_METHOD(SQLite3Stmt, execute)
1776 {
1777 php_sqlite3_stmt *stmt_obj;
1778 php_sqlite3_result *result;
1779 zval *object = ZEND_THIS;
1780 int return_code = 0;
1781 int bind_rc = 0;
1782
1783 stmt_obj = Z_SQLITE3_STMT_P(object);
1784
1785 ZEND_PARSE_PARAMETERS_NONE();
1786
1787 SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1788
1789 /* Always reset statement before execution, see bug #77051 */
1790 sqlite3_reset(stmt_obj->stmt);
1791
1792 /* Bind parameters to the statement */
1793 bind_rc = php_sqlite3_bind_params(stmt_obj);
1794
1795 if (bind_rc == FAILURE || EG(exception)) {
1796 RETURN_FALSE;
1797 }
1798
1799 return_code = sqlite3_step(stmt_obj->stmt);
1800
1801 switch (return_code) {
1802 case SQLITE_ROW: /* Valid Row */
1803 case SQLITE_DONE: /* Valid but no results */
1804 {
1805 sqlite3_reset(stmt_obj->stmt);
1806 object_init_ex(return_value, php_sqlite3_result_entry);
1807 result = Z_SQLITE3_RESULT_P(return_value);
1808
1809 result->is_prepared_statement = 1;
1810 result->db_obj = stmt_obj->db_obj;
1811 result->stmt_obj = stmt_obj;
1812 result->column_names = NULL;
1813 result->column_count = -1;
1814 ZVAL_OBJ_COPY(&result->stmt_obj_zval, Z_OBJ_P(object));
1815
1816 break;
1817 }
1818 case SQLITE_ERROR:
1819 sqlite3_reset(stmt_obj->stmt);
1820 ZEND_FALLTHROUGH;
1821 default:
1822 if (!EG(exception)) {
1823 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)));
1824 }
1825 zval_ptr_dtor(return_value);
1826 RETURN_FALSE;
1827 }
1828
1829 return;
1830 }
1831 /* }}} */
1832
1833 /* {{{ __constructor for SQLite3Stmt. */
PHP_METHOD(SQLite3Stmt,__construct)1834 PHP_METHOD(SQLite3Stmt, __construct)
1835 {
1836 php_sqlite3_stmt *stmt_obj;
1837 php_sqlite3_db_object *db_obj;
1838 zval *object = ZEND_THIS;
1839 zval *db_zval;
1840 zend_string *sql;
1841 int errcode;
1842 php_sqlite3_free_list *free_item;
1843
1844 stmt_obj = Z_SQLITE3_STMT_P(object);
1845
1846 if (zend_parse_parameters(ZEND_NUM_ARGS(), "OS", &db_zval, php_sqlite3_sc_entry, &sql) == FAILURE) {
1847 RETURN_THROWS();
1848 }
1849
1850 db_obj = Z_SQLITE3_DB_P(db_zval);
1851
1852 SQLITE3_CHECK_INITIALIZED(db_obj, db_obj->initialised, SQLite3)
1853
1854 if (!ZSTR_LEN(sql)) {
1855 RETURN_FALSE;
1856 }
1857
1858 stmt_obj->db_obj = db_obj;
1859 ZVAL_OBJ_COPY(&stmt_obj->db_obj_zval, Z_OBJ_P(db_zval));
1860
1861 errcode = sqlite3_prepare_v2(db_obj->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &(stmt_obj->stmt), NULL);
1862 if (errcode != SQLITE_OK) {
1863 php_sqlite3_error(db_obj, errcode, "Unable to prepare statement: %s", sqlite3_errmsg(db_obj->db));
1864 zval_ptr_dtor(return_value);
1865 RETURN_FALSE;
1866 }
1867 stmt_obj->initialised = 1;
1868
1869 free_item = emalloc(sizeof(php_sqlite3_free_list));
1870 free_item->stmt_obj = stmt_obj;
1871 //?? free_item->stmt_obj_zval = ZEND_THIS;
1872 ZVAL_OBJ(&free_item->stmt_obj_zval, Z_OBJ_P(object));
1873
1874 zend_llist_add_element(&(db_obj->free_list), &free_item);
1875 }
1876 /* }}} */
1877
1878 /* {{{ Number of columns in the result set. */
PHP_METHOD(SQLite3Result,numColumns)1879 PHP_METHOD(SQLite3Result, numColumns)
1880 {
1881 php_sqlite3_result *result_obj;
1882 zval *object = ZEND_THIS;
1883 result_obj = Z_SQLITE3_RESULT_P(object);
1884
1885 ZEND_PARSE_PARAMETERS_NONE();
1886
1887 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1888
1889 RETURN_LONG(sqlite3_column_count(result_obj->stmt_obj->stmt));
1890 }
1891 /* }}} */
1892
1893 /* {{{ Returns the name of the nth column. */
PHP_METHOD(SQLite3Result,columnName)1894 PHP_METHOD(SQLite3Result, columnName)
1895 {
1896 php_sqlite3_result *result_obj;
1897 zval *object = ZEND_THIS;
1898 zend_long column = 0;
1899 char *column_name;
1900 result_obj = Z_SQLITE3_RESULT_P(object);
1901
1902 ZEND_PARSE_PARAMETERS_START(1, 1)
1903 Z_PARAM_LONG(column)
1904 ZEND_PARSE_PARAMETERS_END();
1905
1906 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1907
1908 column_name = (char*) sqlite3_column_name(result_obj->stmt_obj->stmt, column);
1909
1910 if (column_name == NULL) {
1911 RETURN_FALSE;
1912 }
1913
1914 RETVAL_STRING(column_name);
1915 }
1916 /* }}} */
1917
1918 /* {{{ Returns the type of the nth column. */
PHP_METHOD(SQLite3Result,columnType)1919 PHP_METHOD(SQLite3Result, columnType)
1920 {
1921 php_sqlite3_result *result_obj;
1922 zval *object = ZEND_THIS;
1923 zend_long column = 0;
1924 result_obj = Z_SQLITE3_RESULT_P(object);
1925
1926 ZEND_PARSE_PARAMETERS_START(1, 1)
1927 Z_PARAM_LONG(column)
1928 ZEND_PARSE_PARAMETERS_END();
1929
1930 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1931
1932 if (!sqlite3_data_count(result_obj->stmt_obj->stmt)) {
1933 RETURN_FALSE;
1934 }
1935
1936 RETURN_LONG(sqlite3_column_type(result_obj->stmt_obj->stmt, column));
1937 }
1938 /* }}} */
1939
1940 /* {{{ Fetch a result row as both an associative or numerically indexed array or both. */
PHP_METHOD(SQLite3Result,fetchArray)1941 PHP_METHOD(SQLite3Result, fetchArray)
1942 {
1943 php_sqlite3_result *result_obj;
1944 zval *object = ZEND_THIS;
1945 int i, ret;
1946 zend_long mode = PHP_SQLITE3_BOTH;
1947 result_obj = Z_SQLITE3_RESULT_P(object);
1948
1949 ZEND_PARSE_PARAMETERS_START(0, 1)
1950 Z_PARAM_OPTIONAL
1951 Z_PARAM_LONG(mode)
1952 ZEND_PARSE_PARAMETERS_END();
1953
1954 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
1955
1956 ret = sqlite3_step(result_obj->stmt_obj->stmt);
1957 switch (ret) {
1958 case SQLITE_ROW:
1959 /* If there was no return value then just skip fetching */
1960 if (!USED_RET()) {
1961 RETURN_FALSE;
1962 }
1963
1964 if (result_obj->column_count == -1) {
1965 result_obj->column_count = sqlite3_column_count(result_obj->stmt_obj->stmt);
1966 }
1967
1968 int n_cols = result_obj->column_count;
1969
1970 /* Cache column names to speed up repeated fetchArray calls. */
1971 if (mode & PHP_SQLITE3_ASSOC && !result_obj->column_names) {
1972 result_obj->column_names = emalloc(n_cols * sizeof(zend_string*));
1973
1974 for (int i = 0; i < n_cols; i++) {
1975 const char *column = sqlite3_column_name(result_obj->stmt_obj->stmt, i);
1976 result_obj->column_names[i] = zend_string_init(column, strlen(column), 0);
1977 }
1978 }
1979
1980 array_init(return_value);
1981
1982 for (i = 0; i < n_cols; i++) {
1983 zval data;
1984
1985 sqlite_value_to_zval(result_obj->stmt_obj->stmt, i, &data);
1986
1987 if (mode & PHP_SQLITE3_NUM) {
1988 add_index_zval(return_value, i, &data);
1989 }
1990
1991 if (mode & PHP_SQLITE3_ASSOC) {
1992 if (mode & PHP_SQLITE3_NUM) {
1993 if (Z_REFCOUNTED(data)) {
1994 Z_ADDREF(data);
1995 }
1996 }
1997 /* Note: we can't use the "add_new" variant here instead of "update" because
1998 * when the same column name is encountered, the last result should be taken. */
1999 zend_symtable_update(Z_ARR_P(return_value), result_obj->column_names[i], &data);
2000 }
2001 }
2002 break;
2003
2004 case SQLITE_DONE:
2005 RETURN_FALSE;
2006 break;
2007
2008 default:
2009 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)));
2010 }
2011 }
2012 /* }}} */
2013
sqlite3result_clear_column_names_cache(php_sqlite3_result * result)2014 static void sqlite3result_clear_column_names_cache(php_sqlite3_result *result) {
2015 if (result->column_names) {
2016 for (int i = 0; i < result->column_count; i++) {
2017 zend_string_release(result->column_names[i]);
2018 }
2019 efree(result->column_names);
2020 }
2021 result->column_names = NULL;
2022 result->column_count = -1;
2023 }
2024
2025 /* {{{ Resets the result set back to the first row. */
PHP_METHOD(SQLite3Result,reset)2026 PHP_METHOD(SQLite3Result, reset)
2027 {
2028 php_sqlite3_result *result_obj;
2029 zval *object = ZEND_THIS;
2030 result_obj = Z_SQLITE3_RESULT_P(object);
2031
2032 ZEND_PARSE_PARAMETERS_NONE();
2033
2034 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
2035
2036 sqlite3result_clear_column_names_cache(result_obj);
2037
2038 if (sqlite3_reset(result_obj->stmt_obj->stmt) != SQLITE_OK) {
2039 RETURN_FALSE;
2040 }
2041
2042 RETURN_TRUE;
2043 }
2044 /* }}} */
2045
2046 /* {{{ Closes the result set. */
PHP_METHOD(SQLite3Result,finalize)2047 PHP_METHOD(SQLite3Result, finalize)
2048 {
2049 php_sqlite3_result *result_obj;
2050 zval *object = ZEND_THIS;
2051 result_obj = Z_SQLITE3_RESULT_P(object);
2052
2053 ZEND_PARSE_PARAMETERS_NONE();
2054
2055 SQLITE3_CHECK_INITIALIZED(result_obj->db_obj, result_obj->stmt_obj->initialised, SQLite3Result)
2056
2057 sqlite3result_clear_column_names_cache(result_obj);
2058
2059 /* We need to finalize an internal statement */
2060 if (result_obj->is_prepared_statement == 0) {
2061 zend_llist_del_element(&(result_obj->db_obj->free_list), &result_obj->stmt_obj_zval,
2062 (int (*)(void *, void *)) php_sqlite3_compare_stmt_zval_free);
2063 } else {
2064 sqlite3_reset(result_obj->stmt_obj->stmt);
2065 }
2066
2067 RETURN_TRUE;
2068 }
2069 /* }}} */
2070
2071 /* {{{ __constructor for SQLite3Result. */
PHP_METHOD(SQLite3Result,__construct)2072 PHP_METHOD(SQLite3Result, __construct)
2073 {
2074 zend_throw_exception(zend_ce_exception, "SQLite3Result cannot be directly instantiated", 0);
2075 }
2076 /* }}} */
2077
2078 /* {{{ Authorization Callback */
php_sqlite3_authorizer(void * autharg,int action,const char * arg1,const char * arg2,const char * arg3,const char * arg4)2079 static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, const char *arg2, const char *arg3, const char *arg4)
2080 {
2081 /* Check open_basedir restrictions first */
2082 if (PG(open_basedir) && *PG(open_basedir)) {
2083 if (action == SQLITE_ATTACH) {
2084 if (!arg1) {
2085 return SQLITE_DENY;
2086 }
2087 if (memcmp(arg1, ":memory:", sizeof(":memory:")) && *arg1) {
2088 if (strncmp(arg1, "file:", 5) == 0) {
2089 /* starts with "file:" */
2090 return SQLITE_DENY;
2091 } else if (php_check_open_basedir(arg1)) {
2092 return SQLITE_DENY;
2093 }
2094 }
2095 }
2096 }
2097
2098 php_sqlite3_db_object *db_obj = (php_sqlite3_db_object *)autharg;
2099
2100 /* fallback to access allowed if authorizer callback is not defined */
2101 if (!ZEND_FCC_INITIALIZED(db_obj->authorizer_fcc)) {
2102 return SQLITE_OK;
2103 }
2104
2105 /* call userland authorizer callback, if set */
2106 zval retval;
2107 zval argv[5];
2108
2109 ZVAL_LONG(&argv[0], action);
2110
2111 if (NULL == arg1) {
2112 ZVAL_NULL(&argv[1]);
2113 } else {
2114 ZVAL_STRING(&argv[1], arg1);
2115 }
2116
2117 if (NULL == arg2) {
2118 ZVAL_NULL(&argv[2]);
2119 } else {
2120 ZVAL_STRING(&argv[2], arg2);
2121 }
2122
2123 if (NULL == arg3) {
2124 ZVAL_NULL(&argv[3]);
2125 } else {
2126 ZVAL_STRING(&argv[3], arg3);
2127 }
2128
2129 if (NULL == arg4) {
2130 ZVAL_NULL(&argv[4]);
2131 } else {
2132 ZVAL_STRING(&argv[4], arg4);
2133 }
2134
2135 int authreturn = SQLITE_DENY;
2136
2137 zend_call_known_fcc(&db_obj->authorizer_fcc, &retval, /* argc */ 5, argv, /* named_params */ NULL);
2138 if (Z_ISUNDEF(retval)) {
2139 php_sqlite3_error(db_obj, 0, "An error occurred while invoking the authorizer callback");
2140 } else {
2141 if (Z_TYPE(retval) != IS_LONG) {
2142 php_sqlite3_error(db_obj, 0, "The authorizer callback returned an invalid type: expected int");
2143 } else {
2144 authreturn = Z_LVAL(retval);
2145
2146 if (authreturn != SQLITE_OK && authreturn != SQLITE_IGNORE && authreturn != SQLITE_DENY) {
2147 php_sqlite3_error(db_obj, 0, "The authorizer callback returned an invalid value: %d", authreturn);
2148 authreturn = SQLITE_DENY;
2149 }
2150 }
2151 }
2152
2153 /* Free local return and argument values */
2154 zval_ptr_dtor(&retval);
2155 zval_ptr_dtor(&argv[0]);
2156 zval_ptr_dtor(&argv[1]);
2157 zval_ptr_dtor(&argv[2]);
2158 zval_ptr_dtor(&argv[3]);
2159 zval_ptr_dtor(&argv[4]);
2160
2161 return authreturn;
2162 }
2163 /* }}} */
2164
2165 /* {{{ php_sqlite3_free_list_dtor */
php_sqlite3_free_list_dtor(void ** item)2166 static void php_sqlite3_free_list_dtor(void **item)
2167 {
2168 php_sqlite3_free_list *free_item = (php_sqlite3_free_list *)*item;
2169
2170 if (free_item->stmt_obj && free_item->stmt_obj->initialised) {
2171 sqlite3_finalize(free_item->stmt_obj->stmt);
2172 free_item->stmt_obj->initialised = 0;
2173 }
2174 efree(*item);
2175 }
2176 /* }}} */
2177
php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list ** free_list,zval * statement)2178 static int php_sqlite3_compare_stmt_zval_free(php_sqlite3_free_list **free_list, zval *statement ) /* {{{ */
2179 {
2180 return ((*free_list)->stmt_obj->initialised && Z_PTR_P(statement) == Z_PTR((*free_list)->stmt_obj_zval));
2181 }
2182 /* }}} */
2183
php_sqlite3_compare_stmt_free(php_sqlite3_free_list ** free_list,sqlite3_stmt * statement)2184 static int php_sqlite3_compare_stmt_free( php_sqlite3_free_list **free_list, sqlite3_stmt *statement ) /* {{{ */
2185 {
2186 return ((*free_list)->stmt_obj->initialised && statement == (*free_list)->stmt_obj->stmt);
2187 }
2188 /* }}} */
2189
php_sqlite3_object_free_storage(zend_object * object)2190 static void php_sqlite3_object_free_storage(zend_object *object) /* {{{ */
2191 {
2192 php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
2193 php_sqlite3_func *func;
2194 php_sqlite3_collation *collation;
2195
2196 if (!intern) {
2197 return;
2198 }
2199
2200 /* Release function_name from authorizer */
2201 if (ZEND_FCC_INITIALIZED(intern->authorizer_fcc)) {
2202 zend_fcc_dtor(&intern->authorizer_fcc);
2203 }
2204
2205 while (intern->funcs) {
2206 func = intern->funcs;
2207 intern->funcs = func->next;
2208 if (intern->initialised && intern->db) {
2209 sqlite3_create_function(intern->db, func->func_name, func->argc, SQLITE_UTF8, func, NULL, NULL, NULL);
2210 }
2211
2212 efree((char*)func->func_name);
2213
2214 if (ZEND_FCC_INITIALIZED(func->func)) {
2215 zend_fcc_dtor(&func->func);
2216 }
2217 if (ZEND_FCC_INITIALIZED(func->step)) {
2218 zend_fcc_dtor(&func->step);
2219 }
2220 if (ZEND_FCC_INITIALIZED(func->fini)) {
2221 zend_fcc_dtor(&func->fini);
2222 }
2223 efree(func);
2224 }
2225
2226 while (intern->collations){
2227 collation = intern->collations;
2228 intern->collations = collation->next;
2229 if (intern->initialised && intern->db){
2230 sqlite3_create_collation(intern->db, collation->collation_name, SQLITE_UTF8, NULL, NULL);
2231 }
2232 efree((char*)collation->collation_name);
2233 if (ZEND_FCC_INITIALIZED(collation->cmp_func)) {
2234 zend_fcc_dtor(&collation->cmp_func);
2235 }
2236 efree(collation);
2237 }
2238
2239 if (intern->initialised && intern->db) {
2240 sqlite3_close(intern->db);
2241 intern->initialised = 0;
2242 }
2243
2244 zend_object_std_dtor(&intern->zo);
2245 }
2246 /* }}} */
2247
php_sqlite3_gc_buffer_add_fcc(zend_get_gc_buffer * gc_buffer,zend_fcall_info_cache * fcc)2248 static void php_sqlite3_gc_buffer_add_fcc(zend_get_gc_buffer *gc_buffer, zend_fcall_info_cache *fcc)
2249 {
2250 if (ZEND_FCC_INITIALIZED(*fcc)) {
2251 zend_get_gc_buffer_add_fcc(gc_buffer, fcc);
2252 }
2253 }
2254
php_sqlite3_get_gc(zend_object * object,zval ** table,int * n)2255 static HashTable *php_sqlite3_get_gc(zend_object *object, zval **table, int *n)
2256 {
2257 php_sqlite3_db_object *intern = php_sqlite3_db_from_obj(object);
2258
2259 if (intern->funcs == NULL && intern->collations == NULL) {
2260 /* Fast path without allocations */
2261 *table = NULL;
2262 *n = 0;
2263 return zend_std_get_gc(object, table, n);
2264 } else {
2265 zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
2266
2267 php_sqlite3_func *func = intern->funcs;
2268 while (func != NULL) {
2269 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &func->func);
2270 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &func->step);
2271 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &func->fini);
2272 func = func->next;
2273 }
2274
2275 php_sqlite3_collation *collation = intern->collations;
2276 while (collation != NULL) {
2277 php_sqlite3_gc_buffer_add_fcc(gc_buffer, &collation->cmp_func);
2278 collation = collation->next;
2279 }
2280
2281 zend_get_gc_buffer_use(gc_buffer, table, n);
2282
2283 if (object->properties == NULL && object->ce->default_properties_count == 0) {
2284 return NULL;
2285 } else {
2286 return zend_std_get_properties(object);
2287 }
2288 }
2289 }
2290
php_sqlite3_stmt_object_free_storage(zend_object * object)2291 static void php_sqlite3_stmt_object_free_storage(zend_object *object) /* {{{ */
2292 {
2293 php_sqlite3_stmt *intern = php_sqlite3_stmt_from_obj(object);
2294
2295 if (!intern) {
2296 return;
2297 }
2298
2299 if (intern->bound_params) {
2300 zend_hash_destroy(intern->bound_params);
2301 FREE_HASHTABLE(intern->bound_params);
2302 intern->bound_params = NULL;
2303 }
2304
2305 if (intern->initialised) {
2306 zend_llist_del_element(&(intern->db_obj->free_list), intern->stmt,
2307 (int (*)(void *, void *)) php_sqlite3_compare_stmt_free);
2308 }
2309
2310 if (!Z_ISUNDEF(intern->db_obj_zval)) {
2311 zval_ptr_dtor(&intern->db_obj_zval);
2312 }
2313
2314 zend_object_std_dtor(&intern->zo);
2315 }
2316 /* }}} */
2317
php_sqlite3_result_object_free_storage(zend_object * object)2318 static void php_sqlite3_result_object_free_storage(zend_object *object) /* {{{ */
2319 {
2320 php_sqlite3_result *intern = php_sqlite3_result_from_obj(object);
2321
2322 if (!intern) {
2323 return;
2324 }
2325
2326 sqlite3result_clear_column_names_cache(intern);
2327
2328 if (!Z_ISNULL(intern->stmt_obj_zval)) {
2329 if (intern->stmt_obj && intern->stmt_obj->initialised) {
2330 sqlite3_reset(intern->stmt_obj->stmt);
2331 }
2332
2333 zval_ptr_dtor(&intern->stmt_obj_zval);
2334 }
2335
2336 zend_object_std_dtor(&intern->zo);
2337 }
2338 /* }}} */
2339
php_sqlite3_object_new(zend_class_entry * class_type)2340 static zend_object *php_sqlite3_object_new(zend_class_entry *class_type) /* {{{ */
2341 {
2342 php_sqlite3_db_object *intern;
2343
2344 /* Allocate memory for it */
2345 intern = zend_object_alloc(sizeof(php_sqlite3_db_object), class_type);
2346
2347 /* Need to keep track of things to free */
2348 zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0);
2349
2350 zend_object_std_init(&intern->zo, class_type);
2351 object_properties_init(&intern->zo, class_type);
2352
2353 return &intern->zo;
2354 }
2355 /* }}} */
2356
php_sqlite3_stmt_object_new(zend_class_entry * class_type)2357 static zend_object *php_sqlite3_stmt_object_new(zend_class_entry *class_type) /* {{{ */
2358 {
2359 php_sqlite3_stmt *intern;
2360
2361 /* Allocate memory for it */
2362 intern = zend_object_alloc(sizeof(php_sqlite3_stmt), class_type);
2363
2364 zend_object_std_init(&intern->zo, class_type);
2365 object_properties_init(&intern->zo, class_type);
2366
2367 return &intern->zo;
2368 }
2369 /* }}} */
2370
php_sqlite3_result_object_new(zend_class_entry * class_type)2371 static zend_object *php_sqlite3_result_object_new(zend_class_entry *class_type) /* {{{ */
2372 {
2373 php_sqlite3_result *intern;
2374
2375 /* Allocate memory for it */
2376 intern = zend_object_alloc(sizeof(php_sqlite3_result), class_type);
2377
2378 zend_object_std_init(&intern->zo, class_type);
2379 object_properties_init(&intern->zo, class_type);
2380
2381 return &intern->zo;
2382 }
2383 /* }}} */
2384
sqlite3_param_dtor(zval * data)2385 static void sqlite3_param_dtor(zval *data) /* {{{ */
2386 {
2387 struct php_sqlite3_bound_param *param = (struct php_sqlite3_bound_param*)Z_PTR_P(data);
2388
2389 if (param->name) {
2390 zend_string_release_ex(param->name, 0);
2391 }
2392
2393 if (!Z_ISNULL(param->parameter)) {
2394 zval_ptr_dtor(&(param->parameter));
2395 ZVAL_UNDEF(¶m->parameter);
2396 }
2397 efree(param);
2398 }
2399 /* }}} */
2400
2401 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(sqlite3)2402 PHP_MINIT_FUNCTION(sqlite3)
2403 {
2404 /* Register SQLite3Exception class */
2405 php_sqlite3_exception_ce = register_class_SQLite3Exception(zend_ce_exception);
2406
2407 #ifdef ZTS
2408 /* Refuse to load if this wasn't a threasafe library loaded */
2409 if (!sqlite3_threadsafe()) {
2410 php_error_docref(NULL, E_WARNING, "A thread safe version of SQLite is required when using a thread safe version of PHP.");
2411 return FAILURE;
2412 }
2413 #endif
2414
2415 memcpy(&sqlite3_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2416 memcpy(&sqlite3_stmt_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2417 memcpy(&sqlite3_result_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
2418
2419 /* Register SQLite 3 Class */
2420 sqlite3_object_handlers.offset = XtOffsetOf(php_sqlite3_db_object, zo);
2421 sqlite3_object_handlers.clone_obj = NULL;
2422 sqlite3_object_handlers.free_obj = php_sqlite3_object_free_storage;
2423 sqlite3_object_handlers.get_gc = php_sqlite3_get_gc;
2424 php_sqlite3_sc_entry = register_class_SQLite3();
2425 php_sqlite3_sc_entry->create_object = php_sqlite3_object_new;
2426 php_sqlite3_sc_entry->default_object_handlers = &sqlite3_object_handlers;
2427
2428 /* Register SQLite 3 Prepared Statement Class */
2429 sqlite3_stmt_object_handlers.offset = XtOffsetOf(php_sqlite3_stmt, zo);
2430 sqlite3_stmt_object_handlers.clone_obj = NULL;
2431 sqlite3_stmt_object_handlers.free_obj = php_sqlite3_stmt_object_free_storage;
2432 php_sqlite3_stmt_entry = register_class_SQLite3Stmt();
2433 php_sqlite3_stmt_entry->create_object = php_sqlite3_stmt_object_new;
2434 php_sqlite3_stmt_entry->default_object_handlers = &sqlite3_stmt_object_handlers;
2435
2436 /* Register SQLite 3 Result Class */
2437 sqlite3_result_object_handlers.offset = XtOffsetOf(php_sqlite3_result, zo);
2438 sqlite3_result_object_handlers.clone_obj = NULL;
2439 sqlite3_result_object_handlers.free_obj = php_sqlite3_result_object_free_storage;
2440 php_sqlite3_result_entry = register_class_SQLite3Result();
2441 php_sqlite3_result_entry->create_object = php_sqlite3_result_object_new;
2442 php_sqlite3_result_entry->default_object_handlers = &sqlite3_result_object_handlers;
2443
2444 REGISTER_INI_ENTRIES();
2445
2446 register_sqlite3_symbols(module_number);
2447
2448 return SUCCESS;
2449 }
2450 /* }}} */
2451
2452 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(sqlite3)2453 PHP_MSHUTDOWN_FUNCTION(sqlite3)
2454 {
2455 UNREGISTER_INI_ENTRIES();
2456
2457 return SUCCESS;
2458 }
2459 /* }}} */
2460
2461 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(sqlite3)2462 PHP_MINFO_FUNCTION(sqlite3)
2463 {
2464 php_info_print_table_start();
2465 php_info_print_table_row(2, "SQLite3 support", "enabled");
2466 php_info_print_table_row(2, "SQLite Library", sqlite3_libversion());
2467 php_info_print_table_end();
2468
2469 DISPLAY_INI_ENTRIES();
2470 }
2471 /* }}} */
2472
2473 /* {{{ PHP_GINIT_FUNCTION */
PHP_GINIT_FUNCTION(sqlite3)2474 static PHP_GINIT_FUNCTION(sqlite3)
2475 {
2476 #if defined(COMPILE_DL_SQLITE3) && defined(ZTS)
2477 ZEND_TSRMLS_CACHE_UPDATE();
2478 #endif
2479 memset(sqlite3_globals, 0, sizeof(*sqlite3_globals));
2480 }
2481 /* }}} */
2482
2483 /* {{{ sqlite3_module_entry */
2484 zend_module_entry sqlite3_module_entry = {
2485 STANDARD_MODULE_HEADER,
2486 "sqlite3",
2487 NULL,
2488 PHP_MINIT(sqlite3),
2489 PHP_MSHUTDOWN(sqlite3),
2490 NULL,
2491 NULL,
2492 PHP_MINFO(sqlite3),
2493 PHP_SQLITE3_VERSION,
2494 PHP_MODULE_GLOBALS(sqlite3),
2495 PHP_GINIT(sqlite3),
2496 NULL,
2497 NULL,
2498 STANDARD_MODULE_PROPERTIES_EX
2499 };
2500 /* }}} */
2501
2502 #ifdef COMPILE_DL_SQLITE3
2503 #ifdef ZTS
2504 ZEND_TSRMLS_CACHE_DEFINE()
2505 #endif
2506 ZEND_GET_MODULE(sqlite3)
2507 #endif
2508