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