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