xref: /PHP-8.3/ext/sqlite3/sqlite3.c (revision 49980ee8)
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 = &param->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(&param.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(&param, stmt_obj)) {
1748 		if (!Z_ISUNDEF(param.parameter)) {
1749 			zval_ptr_dtor(&(param.parameter));
1750 			ZVAL_UNDEF(&param.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(&param->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