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