xref: /PHP-7.1/ext/pdo_sqlite/sqlite_driver.c (revision ccd4716e)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2018 The PHP Group                                |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Author: Wez Furlong <wez@php.net>                                    |
16   +----------------------------------------------------------------------+
17 */
18 
19 /* $Id$ */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "pdo/php_pdo.h"
29 #include "pdo/php_pdo_driver.h"
30 #include "php_pdo_sqlite.h"
31 #include "php_pdo_sqlite_int.h"
32 #include "zend_exceptions.h"
33 
_pdo_sqlite_error(pdo_dbh_t * dbh,pdo_stmt_t * stmt,const char * file,int line)34 int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line) /* {{{ */
35 {
36 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
37 	pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
38 	pdo_sqlite_error_info *einfo = &H->einfo;
39 
40 	einfo->errcode = sqlite3_errcode(H->db);
41 	einfo->file = file;
42 	einfo->line = line;
43 
44 	if (einfo->errcode != SQLITE_OK) {
45 		if (einfo->errmsg) {
46 			pefree(einfo->errmsg, dbh->is_persistent);
47 		}
48 		einfo->errmsg = pestrdup((char*)sqlite3_errmsg(H->db), dbh->is_persistent);
49 	} else { /* no error */
50 		strncpy(*pdo_err, PDO_ERR_NONE, sizeof(PDO_ERR_NONE));
51 		return 0;
52 	}
53 	switch (einfo->errcode) {
54 		case SQLITE_NOTFOUND:
55 			strncpy(*pdo_err, "42S02", sizeof("42S02"));
56 			break;
57 
58 		case SQLITE_INTERRUPT:
59 			strncpy(*pdo_err, "01002", sizeof("01002"));
60 			break;
61 
62 		case SQLITE_NOLFS:
63 			strncpy(*pdo_err, "HYC00", sizeof("HYC00"));
64 			break;
65 
66 		case SQLITE_TOOBIG:
67 			strncpy(*pdo_err, "22001", sizeof("22001"));
68 			break;
69 
70 		case SQLITE_CONSTRAINT:
71 			strncpy(*pdo_err, "23000", sizeof("23000"));
72 			break;
73 
74 		case SQLITE_ERROR:
75 		default:
76 			strncpy(*pdo_err, "HY000", sizeof("HY000"));
77 			break;
78 	}
79 
80 	if (!dbh->methods) {
81 		zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode, "SQLSTATE[%s] [%d] %s",
82 				*pdo_err, einfo->errcode, einfo->errmsg);
83 	}
84 
85 	return einfo->errcode;
86 }
87 /* }}} */
88 
pdo_sqlite_fetch_error_func(pdo_dbh_t * dbh,pdo_stmt_t * stmt,zval * info)89 static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info)
90 {
91 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
92 	pdo_sqlite_error_info *einfo = &H->einfo;
93 
94 	if (einfo->errcode) {
95 		add_next_index_long(info, einfo->errcode);
96 		add_next_index_string(info, einfo->errmsg);
97 	}
98 
99 	return 1;
100 }
101 
pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle * H)102 static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
103 {
104 	struct pdo_sqlite_func *func;
105 
106 	while (H->funcs) {
107 		func = H->funcs;
108 		H->funcs = func->next;
109 
110 		if (H->db) {
111 			/* delete the function from the handle */
112 			sqlite3_create_function(H->db,
113 				func->funcname,
114 				func->argc,
115 				SQLITE_UTF8,
116 				func,
117 				NULL, NULL, NULL);
118 		}
119 
120 		efree((char*)func->funcname);
121 		if (!Z_ISUNDEF(func->func)) {
122 			zval_ptr_dtor(&func->func);
123 		}
124 		if (!Z_ISUNDEF(func->step)) {
125 			zval_ptr_dtor(&func->step);
126 		}
127 		if (!Z_ISUNDEF(func->fini)) {
128 			zval_ptr_dtor(&func->fini);
129 		}
130 		efree(func);
131 	}
132 
133 	while (H->collations) {
134 		struct pdo_sqlite_collation *collation;
135 		collation = H->collations;
136 		H->collations = collation->next;
137 
138 		if (H->db) {
139 			/* delete the collation from the handle */
140 			sqlite3_create_collation(H->db,
141 				collation->name,
142 				SQLITE_UTF8,
143 				collation,
144 				NULL);
145 		}
146 
147 		efree((char*)collation->name);
148 		if (!Z_ISUNDEF(collation->callback)) {
149 			zval_ptr_dtor(&collation->callback);
150 		}
151 		efree(collation);
152 	}
153 }
154 
sqlite_handle_closer(pdo_dbh_t * dbh)155 static int sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */
156 {
157 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
158 
159 	if (H) {
160 		pdo_sqlite_error_info *einfo = &H->einfo;
161 
162 		pdo_sqlite_cleanup_callbacks(H);
163 		if (H->db) {
164 			sqlite3_close(H->db);
165 			H->db = NULL;
166 		}
167 		if (einfo->errmsg) {
168 			pefree(einfo->errmsg, dbh->is_persistent);
169 			einfo->errmsg = NULL;
170 		}
171 		pefree(H, dbh->is_persistent);
172 		dbh->driver_data = NULL;
173 	}
174 	return 0;
175 }
176 /* }}} */
177 
sqlite_handle_preparer(pdo_dbh_t * dbh,const char * sql,size_t sql_len,pdo_stmt_t * stmt,zval * driver_options)178 static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options)
179 {
180 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
181 	pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt));
182 	int i;
183 	const char *tail;
184 
185 	S->H = H;
186 	stmt->driver_data = S;
187 	stmt->methods = &sqlite_stmt_methods;
188 	stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL|PDO_PLACEHOLDER_NAMED;
189 
190 	if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY)) {
191 		H->einfo.errcode = SQLITE_ERROR;
192 		pdo_sqlite_error(dbh);
193 		return 0;
194 	}
195 
196 	i = sqlite3_prepare(H->db, sql, sql_len, &S->stmt, &tail);
197 	if (i == SQLITE_OK) {
198 		return 1;
199 	}
200 
201 	pdo_sqlite_error(dbh);
202 
203 	return 0;
204 }
205 
sqlite_handle_doer(pdo_dbh_t * dbh,const char * sql,size_t sql_len)206 static zend_long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
207 {
208 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
209 	char *errmsg = NULL;
210 
211 	if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
212 		pdo_sqlite_error(dbh);
213 		if (errmsg)
214 			sqlite3_free(errmsg);
215 
216 		return -1;
217 	} else {
218 		return sqlite3_changes(H->db);
219 	}
220 }
221 
pdo_sqlite_last_insert_id(pdo_dbh_t * dbh,const char * name,size_t * len)222 static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len)
223 {
224 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
225 	char *id;
226 
227 	id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db));
228 	*len = strlen(id);
229 	return id;
230 }
231 
232 /* NB: doesn't handle binary strings... use prepared stmts for that */
sqlite_handle_quoter(pdo_dbh_t * dbh,const char * unquoted,size_t unquotedlen,char ** quoted,size_t * quotedlen,enum pdo_param_type paramtype)233 static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype )
234 {
235 	*quoted = safe_emalloc(2, unquotedlen, 3);
236 	sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
237 	*quotedlen = strlen(*quoted);
238 	return 1;
239 }
240 
sqlite_handle_begin(pdo_dbh_t * dbh)241 static int sqlite_handle_begin(pdo_dbh_t *dbh)
242 {
243 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
244 	char *errmsg = NULL;
245 
246 	if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
247 		pdo_sqlite_error(dbh);
248 		if (errmsg)
249 			sqlite3_free(errmsg);
250 		return 0;
251 	}
252 	return 1;
253 }
254 
sqlite_handle_commit(pdo_dbh_t * dbh)255 static int sqlite_handle_commit(pdo_dbh_t *dbh)
256 {
257 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
258 	char *errmsg = NULL;
259 
260 	if (sqlite3_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
261 		pdo_sqlite_error(dbh);
262 		if (errmsg)
263 			sqlite3_free(errmsg);
264 		return 0;
265 	}
266 	return 1;
267 }
268 
sqlite_handle_rollback(pdo_dbh_t * dbh)269 static int sqlite_handle_rollback(pdo_dbh_t *dbh)
270 {
271 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
272 	char *errmsg = NULL;
273 
274 	if (sqlite3_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
275 		pdo_sqlite_error(dbh);
276 		if (errmsg)
277 			sqlite3_free(errmsg);
278 		return 0;
279 	}
280 	return 1;
281 }
282 
pdo_sqlite_get_attribute(pdo_dbh_t * dbh,zend_long attr,zval * return_value)283 static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_value)
284 {
285 	switch (attr) {
286 		case PDO_ATTR_CLIENT_VERSION:
287 		case PDO_ATTR_SERVER_VERSION:
288 			ZVAL_STRING(return_value, (char *)sqlite3_libversion());
289 			break;
290 
291 		default:
292 			return 0;
293 	}
294 
295 	return 1;
296 }
297 
pdo_sqlite_set_attr(pdo_dbh_t * dbh,zend_long attr,zval * val)298 static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
299 {
300 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
301 
302 	switch (attr) {
303 		case PDO_ATTR_TIMEOUT:
304 			sqlite3_busy_timeout(H->db, zval_get_long(val) * 1000);
305 			return 1;
306 	}
307 	return 0;
308 }
309 
do_callback(struct pdo_sqlite_fci * fc,zval * cb,int argc,sqlite3_value ** argv,sqlite3_context * context,int is_agg)310 static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
311 		int argc, sqlite3_value **argv, sqlite3_context *context,
312 		int is_agg)
313 {
314 	zval *zargs = NULL;
315 	zval retval;
316 	int i;
317 	int ret;
318 	int fake_argc;
319 	zend_reference *agg_context = NULL;
320 
321 	if (is_agg) {
322 		is_agg = 2;
323 	}
324 
325 	fake_argc = argc + is_agg;
326 
327 	fc->fci.size = sizeof(fc->fci);
328 	ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
329 	fc->fci.object = NULL;
330 	fc->fci.retval = &retval;
331 	fc->fci.param_count = fake_argc;
332 
333 	/* build up the params */
334 
335 	if (fake_argc) {
336 		zargs = safe_emalloc(fake_argc, sizeof(zval), 0);
337 	}
338 
339 	if (is_agg) {
340 		agg_context = (zend_reference*)sqlite3_aggregate_context(context, sizeof(zend_reference));
341 		if (!agg_context) {
342 			ZVAL_NULL(&zargs[0]);
343 		} else {
344 			if (Z_ISUNDEF(agg_context->val)) {
345 				GC_REFCOUNT(agg_context) = 1;
346 				GC_TYPE_INFO(agg_context) = IS_REFERENCE;
347 				ZVAL_NULL(&agg_context->val);
348 			}
349 			ZVAL_REF(&zargs[0], agg_context);
350 		}
351 		ZVAL_LONG(&zargs[1], sqlite3_aggregate_count(context));
352 	}
353 
354 	for (i = 0; i < argc; i++) {
355 		/* get the value */
356 		switch (sqlite3_value_type(argv[i])) {
357 			case SQLITE_INTEGER:
358 				ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
359 				break;
360 
361 			case SQLITE_FLOAT:
362 				ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
363 				break;
364 
365 			case SQLITE_NULL:
366 				ZVAL_NULL(&zargs[i + is_agg]);
367 				break;
368 
369 			case SQLITE_BLOB:
370 			case SQLITE3_TEXT:
371 			default:
372 				ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
373 				break;
374 		}
375 	}
376 
377 	fc->fci.params = zargs;
378 
379 	if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) {
380 		php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
381 	}
382 
383 	/* clean up the params */
384 	if (zargs) {
385 		for (i = is_agg; i < fake_argc; i++) {
386 			zval_ptr_dtor(&zargs[i]);
387 		}
388 		if (is_agg) {
389 			zval_ptr_dtor(&zargs[1]);
390 		}
391 		efree(zargs);
392 	}
393 
394 	if (!is_agg || !argv) {
395 		/* only set the sqlite return value if we are a scalar function,
396 		 * or if we are finalizing an aggregate */
397 		if (!Z_ISUNDEF(retval)) {
398 			switch (Z_TYPE(retval)) {
399 				case IS_LONG:
400 					sqlite3_result_int(context, Z_LVAL(retval));
401 					break;
402 
403 				case IS_NULL:
404 					sqlite3_result_null(context);
405 					break;
406 
407 				case IS_DOUBLE:
408 					sqlite3_result_double(context, Z_DVAL(retval));
409 					break;
410 
411 				default:
412 					convert_to_string_ex(&retval);
413 					sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT);
414 					break;
415 			}
416 		} else {
417 			sqlite3_result_error(context, "failed to invoke callback", 0);
418 		}
419 
420 		if (agg_context) {
421 			zval_ptr_dtor(&agg_context->val);
422 		}
423 	} else {
424 		/* we're stepping in an aggregate; the return value goes into
425 		 * the context */
426 		if (agg_context) {
427 			zval_ptr_dtor(&agg_context->val);
428 		}
429 		if (!Z_ISUNDEF(retval)) {
430 			ZVAL_COPY_VALUE(&agg_context->val, &retval);
431 			ZVAL_UNDEF(&retval);
432 		} else {
433 			ZVAL_UNDEF(&agg_context->val);
434 		}
435 	}
436 
437 	if (!Z_ISUNDEF(retval)) {
438 		zval_ptr_dtor(&retval);
439 	}
440 
441 	return ret;
442 }
443 
php_sqlite3_func_callback(sqlite3_context * context,int argc,sqlite3_value ** argv)444 static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
445 	sqlite3_value **argv)
446 {
447 	struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
448 
449 	do_callback(&func->afunc, &func->func, argc, argv, context, 0);
450 }
451 
php_sqlite3_func_step_callback(sqlite3_context * context,int argc,sqlite3_value ** argv)452 static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
453 	sqlite3_value **argv)
454 {
455 	struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
456 
457 	do_callback(&func->astep, &func->step, argc, argv, context, 1);
458 }
459 
php_sqlite3_func_final_callback(sqlite3_context * context)460 static void php_sqlite3_func_final_callback(sqlite3_context *context)
461 {
462 	struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
463 
464 	do_callback(&func->afini, &func->fini, 0, NULL, context, 1);
465 }
466 
php_sqlite3_collation_callback(void * context,int string1_len,const void * string1,int string2_len,const void * string2)467 static int php_sqlite3_collation_callback(void *context,
468 	int string1_len, const void *string1,
469 	int string2_len, const void *string2)
470 {
471 	int ret;
472 	zval zargs[2];
473 	zval retval;
474 	struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
475 
476 	collation->fc.fci.size = sizeof(collation->fc.fci);
477 	ZVAL_COPY_VALUE(&collation->fc.fci.function_name, &collation->callback);
478 	collation->fc.fci.object = NULL;
479 	collation->fc.fci.retval = &retval;
480 
481 	// Prepare the arguments.
482 	ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
483 	ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
484 	collation->fc.fci.param_count = 2;
485 	collation->fc.fci.params = zargs;
486 
487 	if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc)) == FAILURE) {
488 		php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
489 	} else if (!Z_ISUNDEF(retval)) {
490 		if (Z_TYPE(retval) != IS_LONG) {
491 			convert_to_long_ex(&retval);
492 		}
493 		ret = 0;
494 		if (Z_LVAL(retval) > 0) {
495 			ret = 1;
496 		} else if (Z_LVAL(retval) < 0) {
497 			ret = -1;
498 		}
499 		zval_ptr_dtor(&retval);
500 	}
501 
502 	zval_ptr_dtor(&zargs[0]);
503 	zval_ptr_dtor(&zargs[1]);
504 
505 	return ret;
506 }
507 
508 /* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount, int flags])
509    Registers a UDF with the sqlite db handle */
PHP_METHOD(SQLite,sqliteCreateFunction)510 static PHP_METHOD(SQLite, sqliteCreateFunction)
511 {
512 	struct pdo_sqlite_func *func;
513 	zval *callback;
514 	char *func_name;
515 	size_t func_name_len;
516 	zend_long argc = -1;
517 	zend_long flags = 0;
518 	zend_string *cbname = NULL;
519 	pdo_dbh_t *dbh;
520 	pdo_sqlite_db_handle *H;
521 	int ret;
522 
523 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz|ll",
524 			&func_name, &func_name_len, &callback, &argc, &flags)) {
525 		RETURN_FALSE;
526 	}
527 
528 	dbh = Z_PDO_DBH_P(getThis());
529 	PDO_CONSTRUCT_CHECK;
530 
531 	if (!zend_is_callable(callback, 0, &cbname)) {
532 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
533 		zend_string_release(cbname);
534 		RETURN_FALSE;
535 	}
536 	zend_string_release(cbname);
537 
538 	H = (pdo_sqlite_db_handle *)dbh->driver_data;
539 
540 	func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
541 
542 	ret = sqlite3_create_function(H->db, func_name, argc, flags | SQLITE_UTF8,
543 			func, php_sqlite3_func_callback, NULL, NULL);
544 	if (ret == SQLITE_OK) {
545 		func->funcname = estrdup(func_name);
546 
547 		ZVAL_COPY(&func->func, callback);
548 
549 		func->argc = argc;
550 
551 		func->next = H->funcs;
552 		H->funcs = func;
553 
554 		RETURN_TRUE;
555 	}
556 
557 	efree(func);
558 	RETURN_FALSE;
559 }
560 /* }}} */
561 
562 /* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount])
563    Registers a UDF with the sqlite db handle */
564 
565 /* The step function should have the prototype:
566    mixed step(mixed $context, int $rownumber, $value [, $value2 [, ...]])
567 
568    $context will be null for the first row; on subsequent rows it will have
569    the value that was previously returned from the step function; you should
570    use this to maintain state for the aggregate.
571 
572    The fini function should have the prototype:
573    mixed fini(mixed $context, int $rownumber)
574 
575    $context will hold the return value from the very last call to the step function.
576    rownumber will hold the number of rows over which the aggregate was performed.
577    The return value of this function will be used as the return value for this
578    aggregate UDF.
579 */
580 
PHP_METHOD(SQLite,sqliteCreateAggregate)581 static PHP_METHOD(SQLite, sqliteCreateAggregate)
582 {
583 	struct pdo_sqlite_func *func;
584 	zval *step_callback, *fini_callback;
585 	char *func_name;
586 	size_t func_name_len;
587 	zend_long argc = -1;
588 	zend_string *cbname = NULL;
589 	pdo_dbh_t *dbh;
590 	pdo_sqlite_db_handle *H;
591 	int ret;
592 
593 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l",
594 			&func_name, &func_name_len, &step_callback, &fini_callback, &argc)) {
595 		RETURN_FALSE;
596 	}
597 
598 	dbh = Z_PDO_DBH_P(getThis());
599 	PDO_CONSTRUCT_CHECK;
600 
601 	if (!zend_is_callable(step_callback, 0, &cbname)) {
602 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
603 		zend_string_release(cbname);
604 		RETURN_FALSE;
605 	}
606 	zend_string_release(cbname);
607 	if (!zend_is_callable(fini_callback, 0, &cbname)) {
608 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
609 		zend_string_release(cbname);
610 		RETURN_FALSE;
611 	}
612 	zend_string_release(cbname);
613 
614 	H = (pdo_sqlite_db_handle *)dbh->driver_data;
615 
616 	func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
617 
618 	ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
619 			func, NULL, php_sqlite3_func_step_callback, php_sqlite3_func_final_callback);
620 	if (ret == SQLITE_OK) {
621 		func->funcname = estrdup(func_name);
622 
623 		ZVAL_COPY(&func->step, step_callback);
624 
625 		ZVAL_COPY(&func->fini, fini_callback);
626 
627 		func->argc = argc;
628 
629 		func->next = H->funcs;
630 		H->funcs = func;
631 
632 		RETURN_TRUE;
633 	}
634 
635 	efree(func);
636 	RETURN_FALSE;
637 }
638 /* }}} */
639 
640 /* {{{ bool SQLite::sqliteCreateCollation(string name, mixed callback)
641    Registers a collation with the sqlite db handle */
PHP_METHOD(SQLite,sqliteCreateCollation)642 static PHP_METHOD(SQLite, sqliteCreateCollation)
643 {
644 	struct pdo_sqlite_collation *collation;
645 	zval *callback;
646 	char *collation_name;
647 	size_t collation_name_len;
648 	zend_string *cbname = NULL;
649 	pdo_dbh_t *dbh;
650 	pdo_sqlite_db_handle *H;
651 	int ret;
652 
653 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz",
654 		&collation_name, &collation_name_len, &callback)) {
655 		RETURN_FALSE;
656 	}
657 
658 	dbh = Z_PDO_DBH_P(getThis());
659 	PDO_CONSTRUCT_CHECK;
660 
661 	if (!zend_is_callable(callback, 0, &cbname)) {
662 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
663 		zend_string_release(cbname);
664 		RETURN_FALSE;
665 	}
666 	zend_string_release(cbname);
667 
668 	H = (pdo_sqlite_db_handle *)dbh->driver_data;
669 
670 	collation = (struct pdo_sqlite_collation*)ecalloc(1, sizeof(*collation));
671 
672 	ret = sqlite3_create_collation(H->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_collation_callback);
673 	if (ret == SQLITE_OK) {
674 		collation->name = estrdup(collation_name);
675 
676 		ZVAL_COPY(&collation->callback, callback);
677 
678 		collation->next = H->collations;
679 		H->collations = collation;
680 
681 		RETURN_TRUE;
682 	}
683 
684 	efree(collation);
685 	RETURN_FALSE;
686 }
687 /* }}} */
688 
689 static const zend_function_entry dbh_methods[] = {
690 	PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
691 	PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
692 	PHP_ME(SQLite, sqliteCreateCollation, NULL, ZEND_ACC_PUBLIC)
693 	PHP_FE_END
694 };
695 
get_driver_methods(pdo_dbh_t * dbh,int kind)696 static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind)
697 {
698 	switch (kind) {
699 		case PDO_DBH_DRIVER_METHOD_KIND_DBH:
700 			return dbh_methods;
701 
702 		default:
703 			return NULL;
704 	}
705 }
706 
pdo_sqlite_request_shutdown(pdo_dbh_t * dbh)707 static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh)
708 {
709 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
710 	/* unregister functions, so that they don't linger for the next
711 	 * request */
712 	if (H) {
713 		pdo_sqlite_cleanup_callbacks(H);
714 	}
715 }
716 
717 static struct pdo_dbh_methods sqlite_methods = {
718 	sqlite_handle_closer,
719 	sqlite_handle_preparer,
720 	sqlite_handle_doer,
721 	sqlite_handle_quoter,
722 	sqlite_handle_begin,
723 	sqlite_handle_commit,
724 	sqlite_handle_rollback,
725 	pdo_sqlite_set_attr,
726 	pdo_sqlite_last_insert_id,
727 	pdo_sqlite_fetch_error_func,
728 	pdo_sqlite_get_attribute,
729 	NULL,	/* check_liveness: not needed */
730 	get_driver_methods,
731 	pdo_sqlite_request_shutdown,
732 	NULL
733 };
734 
make_filename_safe(const char * filename)735 static char *make_filename_safe(const char *filename)
736 {
737 	if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) {
738 		char *fullpath = expand_filepath(filename, NULL);
739 
740 		if (!fullpath) {
741 			return NULL;
742 		}
743 
744 		if (php_check_open_basedir(fullpath)) {
745 			efree(fullpath);
746 			return NULL;
747 		}
748 		return fullpath;
749 	}
750 	return estrdup(filename);
751 }
752 
authorizer(void * autharg,int access_type,const char * arg3,const char * arg4,const char * arg5,const char * arg6)753 static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
754 		const char *arg5, const char *arg6)
755 {
756 	char *filename;
757 	switch (access_type) {
758 		case SQLITE_COPY: {
759 					filename = make_filename_safe(arg4);
760 			if (!filename) {
761 				return SQLITE_DENY;
762 			}
763 			efree(filename);
764 			return SQLITE_OK;
765 		}
766 
767 		case SQLITE_ATTACH: {
768 					filename = make_filename_safe(arg3);
769 			if (!filename) {
770 				return SQLITE_DENY;
771 			}
772 			efree(filename);
773 			return SQLITE_OK;
774 		}
775 
776 		default:
777 			/* access allowed */
778 			return SQLITE_OK;
779 	}
780 }
781 
pdo_sqlite_handle_factory(pdo_dbh_t * dbh,zval * driver_options)782 static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
783 {
784 	pdo_sqlite_db_handle *H;
785 	int i, ret = 0;
786 	zend_long timeout = 60;
787 	char *filename;
788 
789 	H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent);
790 
791 	H->einfo.errcode = 0;
792 	H->einfo.errmsg = NULL;
793 	dbh->driver_data = H;
794 
795 	filename = make_filename_safe(dbh->data_source);
796 
797 	if (!filename) {
798 		zend_throw_exception_ex(php_pdo_get_exception(), 0,
799 			"open_basedir prohibits opening %s",
800 			dbh->data_source);
801 		goto cleanup;
802 	}
803 
804 	i = sqlite3_open(filename, &H->db);
805 	efree(filename);
806 
807 	if (i != SQLITE_OK) {
808 		pdo_sqlite_error(dbh);
809 		goto cleanup;
810 	}
811 
812 	if (PG(open_basedir) && *PG(open_basedir)) {
813 		sqlite3_set_authorizer(H->db, authorizer, NULL);
814 	}
815 
816 	if (driver_options) {
817 		timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout);
818 	}
819 	sqlite3_busy_timeout(H->db, timeout * 1000);
820 
821 	dbh->alloc_own_columns = 1;
822 	dbh->max_escaped_char_length = 2;
823 
824 	ret = 1;
825 
826 cleanup:
827 	dbh->methods = &sqlite_methods;
828 
829 	return ret;
830 }
831 /* }}} */
832 
833 pdo_driver_t pdo_sqlite_driver = {
834 	PDO_DRIVER_HEADER(sqlite),
835 	pdo_sqlite_handle_factory
836 };
837 
838 /*
839  * Local variables:
840  * tab-width: 4
841  * c-basic-offset: 4
842  * End:
843  * vim600: noet sw=4 ts=4 fdm=marker
844  * vim<600: noet sw=4 ts=4
845  */
846