Annotation of embedaddon/php/ext/pdo_sqlite/sqlite_driver.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 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: sqlite_driver.c 321634 2012-01-01 13:15:04Z felipe $ */
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:
34: int _pdo_sqlite_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *file, int line TSRMLS_DC) /* {{{ */
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 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
82: *pdo_err, einfo->errcode, einfo->errmsg);
83: }
84:
85: return einfo->errcode;
86: }
87: /* }}} */
88:
89: static int pdo_sqlite_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
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, 1);
97: }
98:
99: return 1;
100: }
101:
102: static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H TSRMLS_DC)
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 (func->func) {
122: zval_ptr_dtor(&func->func);
123: }
124: if (func->step) {
125: zval_ptr_dtor(&func->step);
126: }
127: if (func->fini) {
128: zval_ptr_dtor(&func->fini);
129: }
130: efree(func);
131: }
132: }
133:
134: static int sqlite_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
135: {
136: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
137:
138: if (H) {
139: pdo_sqlite_error_info *einfo = &H->einfo;
140:
141: pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
142: if (H->db) {
143: sqlite3_close(H->db);
144: H->db = NULL;
145: }
146: if (einfo->errmsg) {
147: pefree(einfo->errmsg, dbh->is_persistent);
148: einfo->errmsg = NULL;
149: }
150: pefree(H, dbh->is_persistent);
151: dbh->driver_data = NULL;
152: }
153: return 0;
154: }
155: /* }}} */
156:
157: static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
158: {
159: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
160: pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt));
161: int i;
162: const char *tail;
163:
164: S->H = H;
165: stmt->driver_data = S;
166: stmt->methods = &sqlite_stmt_methods;
167: stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL|PDO_PLACEHOLDER_NAMED;
168:
169: if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
170: H->einfo.errcode = SQLITE_ERROR;
171: pdo_sqlite_error(dbh);
172: return 0;
173: }
174:
175: i = sqlite3_prepare(H->db, sql, sql_len, &S->stmt, &tail);
176: if (i == SQLITE_OK) {
177: return 1;
178: }
179:
180: pdo_sqlite_error(dbh);
181:
182: return 0;
183: }
184:
185: static long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
186: {
187: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
188: char *errmsg = NULL;
189:
190: if (sqlite3_exec(H->db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
191: pdo_sqlite_error(dbh);
192: if (errmsg)
193: sqlite3_free(errmsg);
194:
195: return -1;
196: } else {
197: return sqlite3_changes(H->db);
198: }
199: }
200:
201: static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
202: {
203: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
204: char *id;
205:
206: id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db) TSRMLS_CC);
207: *len = strlen(id);
208: return id;
209: }
210:
211: /* NB: doesn't handle binary strings... use prepared stmts for that */
212: static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
213: {
214: *quoted = safe_emalloc(2, unquotedlen, 3);
215: sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
216: *quotedlen = strlen(*quoted);
217: return 1;
218: }
219:
220: static int sqlite_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
221: {
222: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
223: char *errmsg = NULL;
224:
225: if (sqlite3_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
226: pdo_sqlite_error(dbh);
227: if (errmsg)
228: sqlite3_free(errmsg);
229: return 0;
230: }
231: return 1;
232: }
233:
234: static int sqlite_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
235: {
236: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
237: char *errmsg = NULL;
238:
239: if (sqlite3_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
240: pdo_sqlite_error(dbh);
241: if (errmsg)
242: sqlite3_free(errmsg);
243: return 0;
244: }
245: return 1;
246: }
247:
248: static int sqlite_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
249: {
250: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
251: char *errmsg = NULL;
252:
253: if (sqlite3_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
254: pdo_sqlite_error(dbh);
255: if (errmsg)
256: sqlite3_free(errmsg);
257: return 0;
258: }
259: return 1;
260: }
261:
262: static int pdo_sqlite_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
263: {
264: switch (attr) {
265: case PDO_ATTR_CLIENT_VERSION:
266: case PDO_ATTR_SERVER_VERSION:
267: ZVAL_STRING(return_value, (char *)sqlite3_libversion(), 1);
268: break;
269:
270: default:
271: return 0;
272: }
273:
274: return 1;
275: }
276:
277: static int pdo_sqlite_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
278: {
279: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
280:
281: switch (attr) {
282: case PDO_ATTR_TIMEOUT:
283: convert_to_long(val);
284: sqlite3_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
285: return 1;
286: }
287: return 0;
288: }
289:
290: static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
291: int argc, sqlite3_value **argv, sqlite3_context *context,
292: int is_agg TSRMLS_DC)
293: {
294: zval ***zargs = NULL;
295: zval *retval = NULL;
296: int i;
297: int ret;
298: int fake_argc;
299: zval **agg_context = NULL;
300:
301: if (is_agg) {
302: is_agg = 2;
303: }
304:
305: fake_argc = argc + is_agg;
306:
307: fc->fci.size = sizeof(fc->fci);
308: fc->fci.function_table = EG(function_table);
309: fc->fci.function_name = cb;
310: fc->fci.symbol_table = NULL;
311: fc->fci.object_ptr = NULL;
312: fc->fci.retval_ptr_ptr = &retval;
313: fc->fci.param_count = fake_argc;
314:
315: /* build up the params */
316:
317: if (fake_argc) {
318: zargs = (zval ***)safe_emalloc(fake_argc, sizeof(zval **), 0);
319: }
320:
321: if (is_agg) {
322: /* summon the aggregation context */
323: agg_context = (zval**)sqlite3_aggregate_context(context, sizeof(zval*));
324: if (!*agg_context) {
325: MAKE_STD_ZVAL(*agg_context);
326: ZVAL_NULL(*agg_context);
327: }
328: zargs[0] = agg_context;
329:
330: zargs[1] = emalloc(sizeof(zval*));
331: MAKE_STD_ZVAL(*zargs[1]);
332: ZVAL_LONG(*zargs[1], sqlite3_aggregate_count(context));
333: }
334:
335: for (i = 0; i < argc; i++) {
336: zargs[i + is_agg] = emalloc(sizeof(zval *));
337: MAKE_STD_ZVAL(*zargs[i + is_agg]);
338:
339: /* get the value */
340: switch (sqlite3_value_type(argv[i])) {
341: case SQLITE_INTEGER:
342: ZVAL_LONG(*zargs[i + is_agg], sqlite3_value_int(argv[i]));
343: break;
344:
345: case SQLITE_FLOAT:
346: ZVAL_DOUBLE(*zargs[i + is_agg], sqlite3_value_double(argv[i]));
347: break;
348:
349: case SQLITE_NULL:
350: ZVAL_NULL(*zargs[i + is_agg]);
351: break;
352:
353: case SQLITE_BLOB:
354: case SQLITE3_TEXT:
355: default:
356: ZVAL_STRINGL(*zargs[i + is_agg], (char*)sqlite3_value_text(argv[i]),
357: sqlite3_value_bytes(argv[i]), 1);
358: break;
359: }
360: }
361:
362:
363: fc->fci.params = zargs;
364:
365:
366: if ((ret = zend_call_function(&fc->fci, &fc->fcc TSRMLS_CC)) == FAILURE) {
367: php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the callback");
368: }
369:
370: /* clean up the params */
371: if (zargs) {
372: for (i = is_agg; i < fake_argc; i++) {
373: zval_ptr_dtor(zargs[i]);
374: efree(zargs[i]);
375: }
376: if (is_agg) {
377: zval_ptr_dtor(zargs[1]);
378: efree(zargs[1]);
379: }
380: efree(zargs);
381: }
382:
383: if (!is_agg || !argv) {
384: /* only set the sqlite return value if we are a scalar function,
385: * or if we are finalizing an aggregate */
386: if (retval) {
387: switch (Z_TYPE_P(retval)) {
388: case IS_LONG:
389: sqlite3_result_int(context, Z_LVAL_P(retval));
390: break;
391:
392: case IS_NULL:
393: sqlite3_result_null(context);
394: break;
395:
396: case IS_DOUBLE:
397: sqlite3_result_double(context, Z_DVAL_P(retval));
398: break;
399:
400: default:
401: convert_to_string_ex(&retval);
402: sqlite3_result_text(context, Z_STRVAL_P(retval),
403: Z_STRLEN_P(retval), SQLITE_TRANSIENT);
404: break;
405: }
406: } else {
407: sqlite3_result_error(context, "failed to invoke callback", 0);
408: }
409:
410: if (agg_context) {
411: zval_ptr_dtor(agg_context);
412: }
413: } else {
414: /* we're stepping in an aggregate; the return value goes into
415: * the context */
416: if (agg_context) {
417: zval_ptr_dtor(agg_context);
418: }
419: if (retval) {
420: *agg_context = retval;
421: retval = NULL;
422: } else {
423: *agg_context = NULL;
424: }
425: }
426:
427: if (retval) {
428: zval_ptr_dtor(&retval);
429: }
430:
431: return ret;
432: }
433:
434: static void php_sqlite3_func_callback(sqlite3_context *context, int argc,
435: sqlite3_value **argv)
436: {
437: struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
438: TSRMLS_FETCH();
439:
440: do_callback(&func->afunc, func->func, argc, argv, context, 0 TSRMLS_CC);
441: }
442:
443: static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc,
444: sqlite3_value **argv)
445: {
446: struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
447: TSRMLS_FETCH();
448:
449: do_callback(&func->astep, func->step, argc, argv, context, 1 TSRMLS_CC);
450: }
451:
452: static void php_sqlite3_func_final_callback(sqlite3_context *context)
453: {
454: struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
455: TSRMLS_FETCH();
456:
457: do_callback(&func->afini, func->fini, 0, NULL, context, 1 TSRMLS_CC);
458: }
459:
460: /* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount])
461: Registers a UDF with the sqlite db handle */
462: static PHP_METHOD(SQLite, sqliteCreateFunction)
463: {
464: struct pdo_sqlite_func *func;
465: zval *callback;
466: char *func_name;
467: int func_name_len;
468: long argc = -1;
469: char *cbname = NULL;
470: pdo_dbh_t *dbh;
471: pdo_sqlite_db_handle *H;
472: int ret;
473:
474: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l",
475: &func_name, &func_name_len, &callback, &argc)) {
476: RETURN_FALSE;
477: }
478:
479: dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
480: PDO_CONSTRUCT_CHECK;
481:
482: if (!zend_is_callable(callback, 0, &cbname TSRMLS_CC)) {
483: php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
484: efree(cbname);
485: RETURN_FALSE;
486: }
487: efree(cbname);
488:
489: H = (pdo_sqlite_db_handle *)dbh->driver_data;
490:
491: func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
492:
493: ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
494: func, php_sqlite3_func_callback, NULL, NULL);
495: if (ret == SQLITE_OK) {
496: func->funcname = estrdup(func_name);
497:
498: MAKE_STD_ZVAL(func->func);
499: MAKE_COPY_ZVAL(&callback, func->func);
500:
501: func->argc = argc;
502:
503: func->next = H->funcs;
504: H->funcs = func;
505:
506: RETURN_TRUE;
507: }
508:
509: efree(func);
510: RETURN_FALSE;
511: }
512: /* }}} */
513:
514: /* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount])
515: Registers a UDF with the sqlite db handle */
516:
517: /* The step function should have the prototype:
518: mixed step(mixed $context, int $rownumber, $value [, $value2 [, ...]])
519:
520: $context will be null for the first row; on subsequent rows it will have
521: the value that was previously returned from the step function; you should
522: use this to maintain state for the aggregate.
523:
524: The fini function should have the prototype:
525: mixed fini(mixed $context, int $rownumber)
526:
527: $context will hold the return value from the very last call to the step function.
528: rownumber will hold the number of rows over which the aggregate was performed.
529: The return value of this function will be used as the return value for this
530: aggregate UDF.
531: */
532:
533: static PHP_METHOD(SQLite, sqliteCreateAggregate)
534: {
535: struct pdo_sqlite_func *func;
536: zval *step_callback, *fini_callback;
537: char *func_name;
538: int func_name_len;
539: long argc = -1;
540: char *cbname = NULL;
541: pdo_dbh_t *dbh;
542: pdo_sqlite_db_handle *H;
543: int ret;
544:
545: if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l",
546: &func_name, &func_name_len, &step_callback, &fini_callback, &argc)) {
547: RETURN_FALSE;
548: }
549:
550: dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
551: PDO_CONSTRUCT_CHECK;
552:
553: if (!zend_is_callable(step_callback, 0, &cbname TSRMLS_CC)) {
554: php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
555: efree(cbname);
556: RETURN_FALSE;
557: }
558: efree(cbname);
559: if (!zend_is_callable(fini_callback, 0, &cbname TSRMLS_CC)) {
560: php_error_docref(NULL TSRMLS_CC, E_WARNING, "function '%s' is not callable", cbname);
561: efree(cbname);
562: RETURN_FALSE;
563: }
564: efree(cbname);
565:
566: H = (pdo_sqlite_db_handle *)dbh->driver_data;
567:
568: func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func));
569:
570: ret = sqlite3_create_function(H->db, func_name, argc, SQLITE_UTF8,
571: func, NULL, php_sqlite3_func_step_callback, php_sqlite3_func_final_callback);
572: if (ret == SQLITE_OK) {
573: func->funcname = estrdup(func_name);
574:
575: MAKE_STD_ZVAL(func->step);
576: MAKE_COPY_ZVAL(&step_callback, func->step);
577:
578: MAKE_STD_ZVAL(func->fini);
579: MAKE_COPY_ZVAL(&fini_callback, func->fini);
580:
581: func->argc = argc;
582:
583: func->next = H->funcs;
584: H->funcs = func;
585:
586: RETURN_TRUE;
587: }
588:
589: efree(func);
590: RETURN_FALSE;
591: }
592: /* }}} */
593: static const zend_function_entry dbh_methods[] = {
594: PHP_ME(SQLite, sqliteCreateFunction, NULL, ZEND_ACC_PUBLIC)
595: PHP_ME(SQLite, sqliteCreateAggregate, NULL, ZEND_ACC_PUBLIC)
596: PHP_FE_END
597: };
598:
599: static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
600: {
601: switch (kind) {
602: case PDO_DBH_DRIVER_METHOD_KIND_DBH:
603: return dbh_methods;
604:
605: default:
606: return NULL;
607: }
608: }
609:
610: static void pdo_sqlite_request_shutdown(pdo_dbh_t *dbh TSRMLS_DC)
611: {
612: pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
613: /* unregister functions, so that they don't linger for the next
614: * request */
615: if (H) {
616: pdo_sqlite_cleanup_callbacks(H TSRMLS_CC);
617: }
618: }
619:
620: static struct pdo_dbh_methods sqlite_methods = {
621: sqlite_handle_closer,
622: sqlite_handle_preparer,
623: sqlite_handle_doer,
624: sqlite_handle_quoter,
625: sqlite_handle_begin,
626: sqlite_handle_commit,
627: sqlite_handle_rollback,
628: pdo_sqlite_set_attr,
629: pdo_sqlite_last_insert_id,
630: pdo_sqlite_fetch_error_func,
631: pdo_sqlite_get_attribute,
632: NULL, /* check_liveness: not needed */
633: get_driver_methods,
634: pdo_sqlite_request_shutdown
635: };
636:
637: static char *make_filename_safe(const char *filename TSRMLS_DC)
638: {
639: if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
640: char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
641:
642: if (!fullpath) {
643: return NULL;
644: }
645:
646: if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
647: efree(fullpath);
648: return NULL;
649: }
650:
651: if (php_check_open_basedir(fullpath TSRMLS_CC)) {
652: efree(fullpath);
653: return NULL;
654: }
655: return fullpath;
656: }
657: return estrdup(filename);
658: }
659:
660: static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
661: const char *arg5, const char *arg6)
662: {
663: char *filename;
664: switch (access_type) {
665: case SQLITE_COPY: {
666: TSRMLS_FETCH();
667: filename = make_filename_safe(arg4 TSRMLS_CC);
668: if (!filename) {
669: return SQLITE_DENY;
670: }
671: efree(filename);
672: return SQLITE_OK;
673: }
674:
675: case SQLITE_ATTACH: {
676: TSRMLS_FETCH();
677: filename = make_filename_safe(arg3 TSRMLS_CC);
678: if (!filename) {
679: return SQLITE_DENY;
680: }
681: efree(filename);
682: return SQLITE_OK;
683: }
684:
685: default:
686: /* access allowed */
687: return SQLITE_OK;
688: }
689: }
690:
691: static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
692: {
693: pdo_sqlite_db_handle *H;
694: int i, ret = 0;
695: long timeout = 60;
696: char *filename;
697:
698: H = pecalloc(1, sizeof(pdo_sqlite_db_handle), dbh->is_persistent);
699:
700: H->einfo.errcode = 0;
701: H->einfo.errmsg = NULL;
702: dbh->driver_data = H;
703:
704: filename = make_filename_safe(dbh->data_source TSRMLS_CC);
705:
706: if (!filename) {
707: zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
708: "safe_mode/open_basedir prohibits opening %s",
709: dbh->data_source);
710: goto cleanup;
711: }
712:
713: i = sqlite3_open(filename, &H->db);
714: efree(filename);
715:
716: if (i != SQLITE_OK) {
717: pdo_sqlite_error(dbh);
718: goto cleanup;
719: }
720:
721: if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
722: sqlite3_set_authorizer(H->db, authorizer, NULL);
723: }
724:
725: if (driver_options) {
726: timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
727: }
728: sqlite3_busy_timeout(H->db, timeout * 1000);
729:
730: dbh->alloc_own_columns = 1;
731: dbh->max_escaped_char_length = 2;
732:
733: ret = 1;
734:
735: cleanup:
736: dbh->methods = &sqlite_methods;
737:
738: return ret;
739: }
740: /* }}} */
741:
742: pdo_driver_t pdo_sqlite_driver = {
743: PDO_DRIVER_HEADER(sqlite),
744: pdo_sqlite_handle_factory
745: };
746:
747: /*
748: * Local variables:
749: * tab-width: 4
750: * c-basic-offset: 4
751: * End:
752: * vim600: noet sw=4 ts=4 fdm=marker
753: * vim<600: noet sw=4 ts=4
754: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>