xref: /PHP-7.0/ext/pdo_sqlite/sqlite_driver.c (revision 478f119a)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2017 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 	fc->fci.function_table = EG(function_table);
329 	ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
330 	fc->fci.symbol_table = NULL;
331 	fc->fci.object = NULL;
332 	fc->fci.retval = &retval;
333 	fc->fci.param_count = fake_argc;
334 
335 	/* build up the params */
336 
337 	if (fake_argc) {
338 		zargs = safe_emalloc(fake_argc, sizeof(zval), 0);
339 	}
340 
341 	if (is_agg) {
342 		agg_context = (zend_reference*)sqlite3_aggregate_context(context, sizeof(zend_reference));
343 		if (!agg_context) {
344 			ZVAL_NULL(&zargs[0]);
345 		} else {
346 			if (Z_ISUNDEF(agg_context->val)) {
347 				GC_REFCOUNT(agg_context) = 1;
348 				GC_TYPE_INFO(agg_context) = IS_REFERENCE;
349 				ZVAL_NULL(&agg_context->val);
350 			}
351 			ZVAL_REF(&zargs[0], agg_context);
352 		}
353 		ZVAL_LONG(&zargs[1], sqlite3_aggregate_count(context));
354 	}
355 
356 	for (i = 0; i < argc; i++) {
357 		/* get the value */
358 		switch (sqlite3_value_type(argv[i])) {
359 			case SQLITE_INTEGER:
360 				ZVAL_LONG(&zargs[i + is_agg], sqlite3_value_int(argv[i]));
361 				break;
362 
363 			case SQLITE_FLOAT:
364 				ZVAL_DOUBLE(&zargs[i + is_agg], sqlite3_value_double(argv[i]));
365 				break;
366 
367 			case SQLITE_NULL:
368 				ZVAL_NULL(&zargs[i + is_agg]);
369 				break;
370 
371 			case SQLITE_BLOB:
372 			case SQLITE3_TEXT:
373 			default:
374 				ZVAL_STRINGL(&zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]), sqlite3_value_bytes(argv[i]));
375 				break;
376 		}
377 	}
378 
379 	fc->fci.params = zargs;
380 
381 	if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) {
382 		php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
383 	}
384 
385 	/* clean up the params */
386 	if (zargs) {
387 		for (i = is_agg; i < fake_argc; i++) {
388 			zval_ptr_dtor(&zargs[i]);
389 		}
390 		if (is_agg) {
391 			zval_ptr_dtor(&zargs[1]);
392 		}
393 		efree(zargs);
394 	}
395 
396 	if (!is_agg || !argv) {
397 		/* only set the sqlite return value if we are a scalar function,
398 		 * or if we are finalizing an aggregate */
399 		if (!Z_ISUNDEF(retval)) {
400 			switch (Z_TYPE(retval)) {
401 				case IS_LONG:
402 					sqlite3_result_int(context, Z_LVAL(retval));
403 					break;
404 
405 				case IS_NULL:
406 					sqlite3_result_null(context);
407 					break;
408 
409 				case IS_DOUBLE:
410 					sqlite3_result_double(context, Z_DVAL(retval));
411 					break;
412 
413 				default:
414 					convert_to_string_ex(&retval);
415 					sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT);
416 					break;
417 			}
418 		} else {
419 			sqlite3_result_error(context, "failed to invoke callback", 0);
420 		}
421 
422 		if (agg_context) {
423 			zval_ptr_dtor(&agg_context->val);
424 		}
425 	} else {
426 		/* we're stepping in an aggregate; the return value goes into
427 		 * the context */
428 		if (agg_context) {
429 			zval_ptr_dtor(&agg_context->val);
430 		}
431 		if (!Z_ISUNDEF(retval)) {
432 			ZVAL_COPY_VALUE(&agg_context->val, &retval);
433 			ZVAL_UNDEF(&retval);
434 		} else {
435 			ZVAL_UNDEF(&agg_context->val);
436 		}
437 	}
438 
439 	if (!Z_ISUNDEF(retval)) {
440 		zval_ptr_dtor(&retval);
441 	}
442 
443 	return ret;
444 }
445 
php_sqlite3_func_callback(sqlite3_context * context,int argc,sqlite3_value ** argv)446 static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
447 	sqlite3_value **argv)
448 {
449 	struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
450 
451 	do_callback(&func->afunc, &func->func, argc, argv, context, 0);
452 }
453 
php_sqlite3_func_step_callback(sqlite3_context * context,int argc,sqlite3_value ** argv)454 static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
455 	sqlite3_value **argv)
456 {
457 	struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
458 
459 	do_callback(&func->astep, &func->step, argc, argv, context, 1);
460 }
461 
php_sqlite3_func_final_callback(sqlite3_context * context)462 static void php_sqlite3_func_final_callback(sqlite3_context *context)
463 {
464 	struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
465 
466 	do_callback(&func->afini, &func->fini, 0, NULL, context, 1);
467 }
468 
php_sqlite3_collation_callback(void * context,int string1_len,const void * string1,int string2_len,const void * string2)469 static int php_sqlite3_collation_callback(void *context,
470 	int string1_len, const void *string1,
471 	int string2_len, const void *string2)
472 {
473 	int ret;
474 	zval zargs[2];
475 	zval retval;
476 	struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
477 
478 	collation->fc.fci.size = sizeof(collation->fc.fci);
479 	collation->fc.fci.function_table = EG(function_table);
480 	ZVAL_COPY_VALUE(&collation->fc.fci.function_name, &collation->callback);
481 	collation->fc.fci.symbol_table = NULL;
482 	collation->fc.fci.object = NULL;
483 	collation->fc.fci.retval = &retval;
484 
485 	// Prepare the arguments.
486 	ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
487 	ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
488 	collation->fc.fci.param_count = 2;
489 	collation->fc.fci.params = zargs;
490 
491 	if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc)) == FAILURE) {
492 		php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
493 	} else if (!Z_ISUNDEF(retval)) {
494 		if (Z_TYPE(retval) != IS_LONG) {
495 			convert_to_long_ex(&retval);
496 		}
497 		ret = 0;
498 		if (Z_LVAL(retval) > 0) {
499 			ret = 1;
500 		} else if (Z_LVAL(retval) < 0) {
501 			ret = -1;
502 		}
503 		zval_ptr_dtor(&retval);
504 	}
505 
506 	zval_ptr_dtor(&zargs[0]);
507 	zval_ptr_dtor(&zargs[1]);
508 
509 	return ret;
510 }
511 
512 /* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount])
513    Registers a UDF with the sqlite db handle */
PHP_METHOD(SQLite,sqliteCreateFunction)514 static PHP_METHOD(SQLite, sqliteCreateFunction)
515 {
516 	struct pdo_sqlite_func *func;
517 	zval *callback;
518 	char *func_name;
519 	size_t func_name_len;
520 	zend_long argc = -1;
521 	zend_string *cbname = NULL;
522 	pdo_dbh_t *dbh;
523 	pdo_sqlite_db_handle *H;
524 	int ret;
525 
526 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz|l",
527 			&func_name, &func_name_len, &callback, &argc)) {
528 		RETURN_FALSE;
529 	}
530 
531 	dbh = Z_PDO_DBH_P(getThis());
532 	PDO_CONSTRUCT_CHECK;
533 
534 	if (!zend_is_callable(callback, 0, &cbname)) {
535 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
536 		zend_string_release(cbname);
537 		RETURN_FALSE;
538 	}
539 	zend_string_release(cbname);
540 
541 	H = (pdo_sqlite_db_handle *)dbh->driver_data;
542 
543 	func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
544 
545 	ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
546 			func, php_sqlite3_func_callback, NULL, NULL);
547 	if (ret == SQLITE_OK) {
548 		func->funcname = estrdup(func_name);
549 
550 		ZVAL_COPY(&func->func, callback);
551 
552 		func->argc = argc;
553 
554 		func->next = H->funcs;
555 		H->funcs = func;
556 
557 		RETURN_TRUE;
558 	}
559 
560 	efree(func);
561 	RETURN_FALSE;
562 }
563 /* }}} */
564 
565 /* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount])
566    Registers a UDF with the sqlite db handle */
567 
568 /* The step function should have the prototype:
569    mixed step(mixed $context, int $rownumber, $value [, $value2 [, ...]])
570 
571    $context will be null for the first row; on subsequent rows it will have
572    the value that was previously returned from the step function; you should
573    use this to maintain state for the aggregate.
574 
575    The fini function should have the prototype:
576    mixed fini(mixed $context, int $rownumber)
577 
578    $context will hold the return value from the very last call to the step function.
579    rownumber will hold the number of rows over which the aggregate was performed.
580    The return value of this function will be used as the return value for this
581    aggregate UDF.
582 */
583 
PHP_METHOD(SQLite,sqliteCreateAggregate)584 static PHP_METHOD(SQLite, sqliteCreateAggregate)
585 {
586 	struct pdo_sqlite_func *func;
587 	zval *step_callback, *fini_callback;
588 	char *func_name;
589 	size_t func_name_len;
590 	zend_long argc = -1;
591 	zend_string *cbname = NULL;
592 	pdo_dbh_t *dbh;
593 	pdo_sqlite_db_handle *H;
594 	int ret;
595 
596 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l",
597 			&func_name, &func_name_len, &step_callback, &fini_callback, &argc)) {
598 		RETURN_FALSE;
599 	}
600 
601 	dbh = Z_PDO_DBH_P(getThis());
602 	PDO_CONSTRUCT_CHECK;
603 
604 	if (!zend_is_callable(step_callback, 0, &cbname)) {
605 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
606 		zend_string_release(cbname);
607 		RETURN_FALSE;
608 	}
609 	zend_string_release(cbname);
610 	if (!zend_is_callable(fini_callback, 0, &cbname)) {
611 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
612 		zend_string_release(cbname);
613 		RETURN_FALSE;
614 	}
615 	zend_string_release(cbname);
616 
617 	H = (pdo_sqlite_db_handle *)dbh->driver_data;
618 
619 	func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
620 
621 	ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
622 			func, NULL, php_sqlite3_func_step_callback, php_sqlite3_func_final_callback);
623 	if (ret == SQLITE_OK) {
624 		func->funcname = estrdup(func_name);
625 
626 		ZVAL_COPY(&func->step, step_callback);
627 
628 		ZVAL_COPY(&func->fini, fini_callback);
629 
630 		func->argc = argc;
631 
632 		func->next = H->funcs;
633 		H->funcs = func;
634 
635 		RETURN_TRUE;
636 	}
637 
638 	efree(func);
639 	RETURN_FALSE;
640 }
641 /* }}} */
642 
643 /* {{{ bool SQLite::sqliteCreateCollation(string name, mixed callback)
644    Registers a collation with the sqlite db handle */
PHP_METHOD(SQLite,sqliteCreateCollation)645 static PHP_METHOD(SQLite, sqliteCreateCollation)
646 {
647 	struct pdo_sqlite_collation *collation;
648 	zval *callback;
649 	char *collation_name;
650 	size_t collation_name_len;
651 	zend_string *cbname = NULL;
652 	pdo_dbh_t *dbh;
653 	pdo_sqlite_db_handle *H;
654 	int ret;
655 
656 	if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz",
657 		&collation_name, &collation_name_len, &callback)) {
658 		RETURN_FALSE;
659 	}
660 
661 	dbh = Z_PDO_DBH_P(getThis());
662 	PDO_CONSTRUCT_CHECK;
663 
664 	if (!zend_is_callable(callback, 0, &cbname)) {
665 		php_error_docref(NULL, E_WARNING, "function '%s' is not callable", ZSTR_VAL(cbname));
666 		zend_string_release(cbname);
667 		RETURN_FALSE;
668 	}
669 	zend_string_release(cbname);
670 
671 	H = (pdo_sqlite_db_handle *)dbh->driver_data;
672 
673 	collation = (struct pdo_sqlite_collation*)ecalloc(1, sizeof(*collation));
674 
675 	ret = sqlite3_create_collation(H->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_collation_callback);
676 	if (ret == SQLITE_OK) {
677 		collation->name = estrdup(collation_name);
678 
679 		ZVAL_COPY(&collation->callback, callback);
680 
681 		collation->next = H->collations;
682 		H->collations = collation;
683 
684 		RETURN_TRUE;
685 	}
686 
687 	efree(collation);
688 	RETURN_FALSE;
689 }
690 /* }}} */
691 
692 static const zend_function_entry dbh_methods[] = {
693 	PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
694 	PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
695 	PHP_ME(SQLite, sqliteCreateCollation, NULL, ZEND_ACC_PUBLIC)
696 	PHP_FE_END
697 };
698 
get_driver_methods(pdo_dbh_t * dbh,int kind)699 static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind)
700 {
701 	switch (kind) {
702 		case PDO_DBH_DRIVER_METHOD_KIND_DBH:
703 			return dbh_methods;
704 
705 		default:
706 			return NULL;
707 	}
708 }
709 
pdo_sqlite_request_shutdown(pdo_dbh_t * dbh)710 static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh)
711 {
712 	pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
713 	/* unregister functions, so that they don't linger for the next
714 	 * request */
715 	if (H) {
716 		pdo_sqlite_cleanup_callbacks(H);
717 	}
718 }
719 
720 static struct pdo_dbh_methods sqlite_methods = {
721 	sqlite_handle_closer,
722 	sqlite_handle_preparer,
723 	sqlite_handle_doer,
724 	sqlite_handle_quoter,
725 	sqlite_handle_begin,
726 	sqlite_handle_commit,
727 	sqlite_handle_rollback,
728 	pdo_sqlite_set_attr,
729 	pdo_sqlite_last_insert_id,
730 	pdo_sqlite_fetch_error_func,
731 	pdo_sqlite_get_attribute,
732 	NULL,	/* check_liveness: not needed */
733 	get_driver_methods,
734 	pdo_sqlite_request_shutdown
735 };
736 
make_filename_safe(const char * filename)737 static char *make_filename_safe(const char *filename)
738 {
739 	if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) {
740 		char *fullpath = expand_filepath(filename, NULL);
741 
742 		if (!fullpath) {
743 			return NULL;
744 		}
745 
746 		if (php_check_open_basedir(fullpath)) {
747 			efree(fullpath);
748 			return NULL;
749 		}
750 		return fullpath;
751 	}
752 	return estrdup(filename);
753 }
754 
authorizer(void * autharg,int access_type,const char * arg3,const char * arg4,const char * arg5,const char * arg6)755 static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
756 		const char *arg5, const char *arg6)
757 {
758 	char *filename;
759 	switch (access_type) {
760 		case SQLITE_COPY: {
761 					filename = make_filename_safe(arg4);
762 			if (!filename) {
763 				return SQLITE_DENY;
764 			}
765 			efree(filename);
766 			return SQLITE_OK;
767 		}
768 
769 		case SQLITE_ATTACH: {
770 					filename = make_filename_safe(arg3);
771 			if (!filename) {
772 				return SQLITE_DENY;
773 			}
774 			efree(filename);
775 			return SQLITE_OK;
776 		}
777 
778 		default:
779 			/* access allowed */
780 			return SQLITE_OK;
781 	}
782 }
783 
pdo_sqlite_handle_factory(pdo_dbh_t * dbh,zval * driver_options)784 static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
785 {
786 	pdo_sqlite_db_handle *H;
787 	int i, ret = 0;
788 	zend_long timeout = 60;
789 	char *filename;
790 
791 	H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent);
792 
793 	H->einfo.errcode = 0;
794 	H->einfo.errmsg = NULL;
795 	dbh->driver_data = H;
796 
797 	filename = make_filename_safe(dbh->data_source);
798 
799 	if (!filename) {
800 		zend_throw_exception_ex(php_pdo_get_exception(), 0,
801 			"open_basedir prohibits opening %s",
802 			dbh->data_source);
803 		goto cleanup;
804 	}
805 
806 	i = sqlite3_open(filename, &H->db);
807 	efree(filename);
808 
809 	if (i != SQLITE_OK) {
810 		pdo_sqlite_error(dbh);
811 		goto cleanup;
812 	}
813 
814 	if (PG(open_basedir) && *PG(open_basedir)) {
815 		sqlite3_set_authorizer(H->db, authorizer, NULL);
816 	}
817 
818 	if (driver_options) {
819 		timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout);
820 	}
821 	sqlite3_busy_timeout(H->db, timeout * 1000);
822 
823 	dbh->alloc_own_columns = 1;
824 	dbh->max_escaped_char_length = 2;
825 
826 	ret = 1;
827 
828 cleanup:
829 	dbh->methods = &sqlite_methods;
830 
831 	return ret;
832 }
833 /* }}} */
834 
835 pdo_driver_t pdo_sqlite_driver = {
836 	PDO_DRIVER_HEADER(sqlite),
837 	pdo_sqlite_handle_factory
838 };
839 
840 /*
841  * Local variables:
842  * tab-width: 4
843  * c-basic-offset: 4
844  * End:
845  * vim600: noet sw=4 ts=4 fdm=marker
846  * vim<600: noet sw=4 ts=4
847  */
848