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