PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/sqlite - pdo_sqlite2.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 193 287 67.2 %
Date: 2014-07-27 Functions: 19 23 82.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2013 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             : #ifdef HAVE_CONFIG_H
      21             : #include "config.h"
      22             : #endif
      23             : #include "php.h"
      24             : 
      25             : #ifdef PHP_SQLITE2_HAVE_PDO
      26             : #include "sqlite.h"
      27             : #include "pdo/php_pdo.h"
      28             : #include "pdo/php_pdo_driver.h"
      29             : #include "zend_exceptions.h"
      30             : 
      31             : #define php_sqlite_encode_binary(in, n, out) sqlite_encode_binary((const unsigned char *)in, n, (unsigned char *)out)
      32             : #define php_sqlite_decode_binary(in, out)    sqlite_decode_binary((const unsigned char *)in, (unsigned char *)out)
      33             : 
      34             : 
      35             : typedef struct {
      36             :         const char *file;
      37             :         int line;
      38             :         unsigned int errcode;
      39             :         char *errmsg;
      40             : } pdo_sqlite2_error_info;
      41             : 
      42             : typedef struct {
      43             :         sqlite *db;
      44             :         pdo_sqlite2_error_info einfo;
      45             : } pdo_sqlite2_db_handle;
      46             : 
      47             : typedef struct {
      48             :         pdo_sqlite2_db_handle   *H;
      49             :         sqlite_vm *vm;
      50             :         const char **rowdata, **colnames;
      51             :         int ncols;
      52             :         unsigned pre_fetched:1;
      53             :         unsigned done:1;
      54             :         pdo_sqlite2_error_info einfo;
      55             : } pdo_sqlite2_stmt;
      56             : 
      57             : extern int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC);
      58             : #define pdo_sqlite2_error(msg, s) _pdo_sqlite2_error(s, NULL, msg, __FILE__, __LINE__ TSRMLS_CC)
      59             : #define pdo_sqlite2_error_stmt(msg, s) _pdo_sqlite2_error(stmt->dbh, stmt, msg, __FILE__, __LINE__ TSRMLS_CC)
      60             : 
      61             : extern struct pdo_stmt_methods sqlite2_stmt_methods;
      62             : 
      63         106 : static int pdo_sqlite2_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
      64             : {
      65         106 :         pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
      66             : 
      67         106 :         if (S->vm) {
      68          98 :                 char *errmsg = NULL;
      69          98 :                 sqlite_finalize(S->vm, &errmsg);
      70          98 :                 if (errmsg) {
      71           0 :                         sqlite_freemem(errmsg);
      72             :                 }
      73          98 :                 S->vm = NULL;
      74             :         }
      75         106 :         if (S->einfo.errmsg) {
      76           5 :                 pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
      77             :         }
      78         106 :         efree(S);
      79         106 :         return 1;
      80             : }
      81             : 
      82         176 : static int pdo_sqlite2_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
      83             : {
      84         176 :         pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
      85         176 :         char *errmsg = NULL;
      86             :         const char *tail;
      87             : 
      88         176 :         if (stmt->executed && !S->done) {
      89           5 :                 sqlite_finalize(S->vm, &errmsg);
      90           5 :                 pdo_sqlite2_error_stmt(errmsg, stmt);
      91           5 :                 errmsg = NULL;
      92           5 :                 S->vm = NULL;
      93             :         }
      94             : 
      95         176 :         S->einfo.errcode = sqlite_compile(S->H->db, stmt->active_query_string, &tail, &S->vm, &errmsg);
      96         176 :         if (S->einfo.errcode != SQLITE_OK) {
      97           1 :                 pdo_sqlite2_error_stmt(errmsg, stmt);
      98           1 :                 return 0;
      99             :         }
     100             : 
     101         175 :         S->done = 0;
     102         175 :         S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
     103         175 :         switch (S->einfo.errcode) {
     104             :                 case SQLITE_ROW:
     105         126 :                         S->pre_fetched = 1;
     106         126 :                         stmt->column_count = S->ncols;
     107         126 :                         return 1;
     108             : 
     109             :                 case SQLITE_DONE:
     110          48 :                         stmt->column_count = S->ncols;
     111          48 :                         stmt->row_count = sqlite_changes(S->H->db);
     112          48 :                         S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
     113          48 :                         if (S->einfo.errcode != SQLITE_OK) {
     114           0 :                                 pdo_sqlite2_error_stmt(errmsg, stmt);
     115             :                         }
     116          48 :                         S->done = 1;
     117          48 :                         return 1;
     118             : 
     119             :                 case SQLITE_ERROR:
     120             :                 case SQLITE_MISUSE:
     121             :                 case SQLITE_BUSY:
     122             :                 default:
     123           1 :                         pdo_sqlite2_error_stmt(errmsg, stmt);
     124           1 :                         return 0;
     125             :         }
     126             : }
     127             : 
     128         754 : static int pdo_sqlite2_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
     129             :                 enum pdo_param_event event_type TSRMLS_DC)
     130             : {
     131         754 :         return 1;
     132             : }
     133             : 
     134         355 : static int pdo_sqlite2_stmt_fetch(pdo_stmt_t *stmt,
     135             :         enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
     136             : {
     137         355 :         pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
     138         355 :         char *errmsg = NULL;
     139             : 
     140         355 :         if (!S->vm) {
     141           0 :                 return 0;       
     142             :         }
     143         355 :         if (S->pre_fetched) {
     144         122 :                 S->pre_fetched = 0;
     145         122 :                 return 1;
     146             :         }
     147         233 :         if (S->done) {
     148           4 :                 return 0;
     149             :         }
     150             : 
     151         229 :         S->einfo.errcode = sqlite_step(S->vm, &S->ncols, &S->rowdata, &S->colnames);
     152         229 :         switch (S->einfo.errcode) {
     153             :                 case SQLITE_ROW:
     154         131 :                         return 1;
     155             : 
     156             :                 case SQLITE_DONE:
     157          98 :                         S->done = 1;
     158          98 :                         S->einfo.errcode = sqlite_reset(S->vm, &errmsg);
     159          98 :                         if (S->einfo.errcode != SQLITE_OK) {
     160           0 :                                 pdo_sqlite2_error_stmt(errmsg, stmt);
     161           0 :                                 errmsg = NULL;
     162             :                         }
     163          98 :                         return 0;
     164             : 
     165             :                 default:
     166           0 :                         pdo_sqlite2_error_stmt(errmsg, stmt);
     167           0 :                         return 0;
     168             :         }
     169             : }
     170             : 
     171         147 : static int pdo_sqlite2_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
     172             : {
     173         147 :         pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
     174             : 
     175         147 :         if(colno >= S->ncols) {
     176             :                 /* error invalid column */
     177           0 :                 pdo_sqlite2_error_stmt(NULL, stmt);
     178           0 :                 return 0;
     179             :         }
     180             : 
     181         147 :         stmt->columns[colno].name = estrdup(S->colnames[colno]);
     182         147 :         stmt->columns[colno].namelen = strlen(stmt->columns[colno].name);
     183         147 :         stmt->columns[colno].maxlen = 0xffffffff;
     184         147 :         stmt->columns[colno].precision = 0;
     185         147 :         stmt->columns[colno].param_type = PDO_PARAM_STR;
     186             : 
     187         147 :         return 1;
     188             : }
     189             : 
     190         497 : static int pdo_sqlite2_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)
     191             : {
     192         497 :         pdo_sqlite2_stmt *S = (pdo_sqlite2_stmt*)stmt->driver_data;
     193         497 :         if (!S->vm) {
     194           0 :                 return 0;
     195             :         }
     196         497 :         if(colno >= S->ncols) {
     197             :                 /* error invalid column */
     198           0 :                 pdo_sqlite2_error_stmt(NULL, stmt);
     199           0 :                 return 0;
     200             :         }
     201         497 :         if (S->rowdata[colno]) {
     202         490 :                 if (S->rowdata[colno][0] == '\x01') {
     203             :                         /* encoded */
     204           0 :                         *caller_frees = 1;
     205           0 :                         *ptr = emalloc(strlen(S->rowdata[colno]));
     206           0 :                         *len = php_sqlite_decode_binary(S->rowdata[colno]+1, *ptr);
     207           0 :                         (*(char**)ptr)[*len] = '\0';
     208             :                 } else {
     209         490 :                         *ptr = (char*)S->rowdata[colno];
     210         490 :                         *len = strlen(*ptr);
     211             :                 }
     212             :         } else {
     213           7 :                 *ptr = NULL;
     214           7 :                 *len = 0;
     215             :         }
     216         497 :         return 1;
     217             : }
     218             : 
     219             : struct pdo_stmt_methods sqlite2_stmt_methods = {
     220             :         pdo_sqlite2_stmt_dtor,
     221             :         pdo_sqlite2_stmt_execute,
     222             :         pdo_sqlite2_stmt_fetch,
     223             :         pdo_sqlite2_stmt_describe,
     224             :         pdo_sqlite2_stmt_get_col,
     225             :         pdo_sqlite2_stmt_param_hook,
     226             :         NULL, /* set_attr */
     227             :         NULL, /* get_attr */
     228             :         NULL
     229             : };
     230             : 
     231             : 
     232         325 : int _pdo_sqlite2_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */
     233             : {
     234         325 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     235         325 :         pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code;
     236         325 :         pdo_sqlite2_error_info *einfo = &H->einfo;
     237             :         pdo_sqlite2_stmt *S;
     238             : 
     239         325 :         if (stmt) {
     240           7 :                 S = stmt->driver_data;
     241           7 :                 einfo = &S->einfo;
     242             :         }
     243             : 
     244         325 :         einfo->file = file;
     245         325 :         einfo->line = line;
     246             : 
     247         325 :         if (einfo->errmsg) {
     248         215 :                 pefree(einfo->errmsg, dbh->is_persistent);
     249         215 :                 einfo->errmsg = NULL;
     250             :         }
     251             : 
     252         325 :         if (einfo->errcode != SQLITE_OK) {
     253         325 :                 if (errmsg) {
     254         319 :                         einfo->errmsg = pestrdup(errmsg, dbh->is_persistent);
     255         319 :                         sqlite_freemem(errmsg);
     256             :                 } else {
     257           6 :                         einfo->errmsg = pestrdup(sqlite_error_string(einfo->errcode), dbh->is_persistent);
     258             :                 }
     259             :         } else { /* no error */
     260           0 :                 strcpy(*pdo_err, PDO_ERR_NONE);
     261           0 :                 return 0;
     262             :         }
     263         325 :         switch (einfo->errcode) {
     264             :                 case SQLITE_NOTFOUND:
     265           0 :                         strcpy(*pdo_err, "42S02");
     266           0 :                         break;  
     267             : 
     268             :                 case SQLITE_INTERRUPT:
     269           0 :                         strcpy(*pdo_err, "01002");
     270           0 :                         break;
     271             : 
     272             :                 case SQLITE_NOLFS:
     273           0 :                         strcpy(*pdo_err, "HYC00");
     274           0 :                         break;
     275             : 
     276             :                 case SQLITE_TOOBIG:
     277           0 :                         strcpy(*pdo_err, "22001");
     278           0 :                         break;
     279             : 
     280             :                 case SQLITE_CONSTRAINT:
     281           0 :                         strcpy(*pdo_err, "23000");
     282           0 :                         break;
     283             : 
     284             :                 case SQLITE_ERROR:
     285             :                 default:
     286         325 :                         strcpy(*pdo_err, "HY000");
     287             :                         break;
     288             :         }
     289             : 
     290         325 :         if (!dbh->methods) {
     291           0 :                 zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "SQLSTATE[%s] [%d] %s",
     292             :                                 *pdo_err, einfo->errcode, einfo->errmsg);
     293             :         }
     294             : 
     295         325 :         return einfo->errcode;
     296             : }
     297             : /* }}} */
     298             : 
     299           7 : static int pdo_sqlite2_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC)
     300             : {
     301           7 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     302           7 :         pdo_sqlite2_error_info *einfo = &H->einfo;
     303             :         pdo_sqlite2_stmt *S;
     304             : 
     305           7 :         if (stmt) {
     306           4 :                 S = stmt->driver_data;
     307           4 :                 einfo = &S->einfo;
     308             :         }
     309             : 
     310           7 :         if (einfo->errcode) {
     311           7 :                 add_next_index_long(info, einfo->errcode);
     312           7 :                 if (einfo->errmsg) {
     313           3 :                         add_next_index_string(info, einfo->errmsg, 1);
     314             :                 }
     315             :         }
     316             : 
     317           7 :         return 1;
     318             : }
     319             : 
     320         105 : static int sqlite2_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
     321             : {
     322         105 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     323             :         
     324         105 :         if (H) {
     325         105 :                 if (H->db) {
     326         105 :                         sqlite_close(H->db);
     327         105 :                         H->db = NULL;
     328             :                 }
     329         105 :                 if (H->einfo.errmsg) {
     330         104 :                         pefree(H->einfo.errmsg, dbh->is_persistent);
     331         104 :                         H->einfo.errmsg = NULL;
     332             :                 }
     333         105 :                 pefree(H, dbh->is_persistent);
     334         105 :                 dbh->driver_data = NULL;
     335             :         }
     336         105 :         return 0;
     337             : }
     338             : /* }}} */
     339             : 
     340         107 : static int sqlite2_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC)
     341             : {
     342         107 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     343         107 :         pdo_sqlite2_stmt *S = ecalloc(1, sizeof(pdo_sqlite2_stmt));
     344             : 
     345         107 :         S->H = H;
     346         107 :         stmt->driver_data = S;
     347         107 :         stmt->methods = &sqlite2_stmt_methods;
     348         107 :         stmt->supports_placeholders = PDO_PLACEHOLDER_NONE;
     349             : 
     350         107 :         if (PDO_CURSOR_FWDONLY != pdo_attr_lval(driver_options, PDO_ATTR_CURSOR, PDO_CURSOR_FWDONLY TSRMLS_CC)) {
     351           0 :                 H->einfo.errcode = SQLITE_ERROR;
     352           0 :                 pdo_sqlite2_error(NULL, dbh);
     353           0 :                 return 0;
     354             :         }
     355             : 
     356         107 :         return 1;
     357             : }
     358             : 
     359         464 : static long sqlite2_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
     360             : {
     361         464 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     362         464 :         char *errmsg = NULL;
     363             : 
     364         464 :         if ((H->einfo.errcode = sqlite_exec(H->db, sql, NULL, NULL, &errmsg)) != SQLITE_OK) {
     365         318 :                 pdo_sqlite2_error(errmsg, dbh);
     366         318 :                 return -1;
     367             :         } else {
     368         146 :                 return sqlite_changes(H->db);
     369             :         }
     370             : }
     371             : 
     372           0 : static char *pdo_sqlite2_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
     373             : {
     374           0 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     375             :         char *id;
     376             :         
     377           0 :         id = php_pdo_int64_to_str(sqlite_last_insert_rowid(H->db) TSRMLS_CC);
     378           0 :         *len = strlen(id);
     379           0 :         return id;
     380             : }
     381             : 
     382         124 : static int sqlite2_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype  TSRMLS_DC)
     383             : {
     384             :         char *ret;
     385             : 
     386         124 :         if (unquotedlen && (unquoted[0] == '\x01' || memchr(unquoted, '\0', unquotedlen) != NULL)) {
     387             :                 /* binary string */
     388             :                 int len;
     389           0 :                 ret = safe_emalloc(1 + unquotedlen / 254, 257, 5);
     390           0 :                 ret[0] = '\'';
     391           0 :                 ret[1] = '\x01';
     392           0 :                 len = php_sqlite_encode_binary(unquoted, unquotedlen, ret+2);
     393           0 :                 ret[len + 2] = '\'';
     394           0 :                 ret[len + 3] = '\0';
     395           0 :                 *quoted = ret;
     396           0 :                 *quotedlen = len + 3;
     397             :                 /* fprintf(stderr, "Quoting:%d:%.*s:\n", *quotedlen, *quotedlen, *quoted); */
     398           0 :                 return 1;
     399         124 :         } else if (unquotedlen) {
     400         123 :                 ret = sqlite_mprintf("'%q'", unquoted);
     401         123 :                 if (ret) {
     402         123 :                         *quoted = estrdup(ret);
     403         123 :                         *quotedlen = strlen(ret);
     404         123 :                         sqlite_freemem(ret);
     405         123 :                         return 1;
     406             :                 }
     407           0 :                 return 0;
     408             :         } else {
     409           1 :                 *quoted = estrdup("''");
     410           1 :                 *quotedlen = 2;
     411           1 :                 return 1;
     412             :         }
     413             : }
     414             : 
     415           3 : static int sqlite2_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
     416             : {
     417           3 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     418           3 :         char *errmsg = NULL;
     419             : 
     420           3 :         if (sqlite_exec(H->db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
     421           0 :                 pdo_sqlite2_error(errmsg, dbh);
     422           0 :                 return 0;
     423             :         }
     424           3 :         return 1;
     425             : }
     426             : 
     427           1 : static int sqlite2_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
     428             : {
     429           1 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     430           1 :         char *errmsg = NULL;
     431             : 
     432           1 :         if (sqlite_exec(H->db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
     433           0 :                 pdo_sqlite2_error(errmsg, dbh);
     434           0 :                 return 0;
     435             :         }
     436           1 :         return 1;
     437             : }
     438             : 
     439           2 : static int sqlite2_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
     440             : {
     441           2 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     442           2 :         char *errmsg = NULL;
     443             : 
     444           2 :         if (sqlite_exec(H->db, "ROLLBACK", NULL, NULL, &errmsg) != SQLITE_OK) {
     445           0 :                 pdo_sqlite2_error(errmsg, dbh);
     446           0 :                 return 0;
     447             :         }
     448           2 :         return 1;
     449             : }
     450             : 
     451           0 : static int pdo_sqlite2_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
     452             : {
     453           0 :         switch (attr) {
     454             :                 case PDO_ATTR_CLIENT_VERSION:
     455             :                 case PDO_ATTR_SERVER_VERSION:
     456           0 :                         ZVAL_STRING(return_value, (char *)sqlite_libversion(), 1);
     457           0 :                         break;
     458             :                 
     459             :                 default:
     460           0 :                         return 0;       
     461             :         }
     462             : 
     463           0 :         return 1;
     464             : }
     465             : 
     466           1 : static int pdo_sqlite2_set_attr(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC)
     467             : {
     468           1 :         pdo_sqlite2_db_handle *H = (pdo_sqlite2_db_handle *)dbh->driver_data;
     469             : 
     470           1 :         switch (attr) {
     471             :                 case PDO_ATTR_TIMEOUT:
     472           0 :                         convert_to_long(val);
     473           0 :                         sqlite_busy_timeout(H->db, Z_LVAL_P(val) * 1000);
     474           0 :                         return 1;
     475             :         }
     476           1 :         return 0;
     477             : }
     478             : 
     479           0 : static PHP_FUNCTION(sqlite2_create_function)
     480             : {
     481             :         /* TODO: implement this stuff */
     482           0 : }
     483             : 
     484             : static const zend_function_entry dbh_methods[] = {
     485             :         PHP_FE(sqlite2_create_function, NULL)
     486             :         {NULL, NULL, NULL}
     487             : };
     488             : 
     489           0 : static const zend_function_entry *get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
     490             : {
     491           0 :         switch (kind) {
     492             :                 case PDO_DBH_DRIVER_METHOD_KIND_DBH:
     493           0 :                         return dbh_methods;
     494             : 
     495             :                 default:
     496           0 :                         return NULL;
     497             :         }
     498             : }
     499             : 
     500             : static struct pdo_dbh_methods sqlite2_methods = {
     501             :         sqlite2_handle_closer,
     502             :         sqlite2_handle_preparer,
     503             :         sqlite2_handle_doer,
     504             :         sqlite2_handle_quoter,
     505             :         sqlite2_handle_begin,
     506             :         sqlite2_handle_commit,
     507             :         sqlite2_handle_rollback,
     508             :         pdo_sqlite2_set_attr,
     509             :         pdo_sqlite2_last_insert_id,
     510             :         pdo_sqlite2_fetch_error_func,
     511             :         pdo_sqlite2_get_attribute,
     512             :         NULL,   /* check_liveness: not needed */
     513             :         get_driver_methods
     514             : };
     515             : 
     516         106 : static char *make_filename_safe(const char *filename TSRMLS_DC)
     517             : {
     518         106 :         if (*filename && strncmp(filename, ":memory:", sizeof(":memory:")-1)) {
     519           0 :                 char *fullpath = expand_filepath(filename, NULL TSRMLS_CC);
     520             : 
     521           0 :                 if (!fullpath) {
     522           0 :                         return NULL;
     523             :                 }
     524             : 
     525           0 :                 if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
     526           0 :                         efree(fullpath);
     527           0 :                         return NULL;
     528             :                 }
     529             : 
     530           0 :                 if (php_check_open_basedir(fullpath TSRMLS_CC)) {
     531           0 :                         efree(fullpath);
     532           0 :                         return NULL;
     533             :                 }
     534           0 :                 return fullpath;
     535             :         }
     536         106 :         return estrdup(filename);
     537             : }
     538             : 
     539         750 : static int authorizer(void *autharg, int access_type, const char *arg3, const char *arg4,
     540             :                 const char *arg5, const char *arg6)
     541             : {
     542             :         char *filename;
     543         750 :         switch (access_type) {
     544             :                 case SQLITE_COPY: {
     545             :                         TSRMLS_FETCH();
     546           0 :                         filename = make_filename_safe(arg4 TSRMLS_CC);
     547           0 :                         if (!filename) {
     548           0 :                                 return SQLITE_DENY;
     549             :                         }
     550           0 :                         efree(filename);
     551           0 :                         return SQLITE_OK;
     552             :                 }
     553             : 
     554             :                 case SQLITE_ATTACH: {
     555             :                         TSRMLS_FETCH();
     556           0 :                         filename = make_filename_safe(arg3 TSRMLS_CC);
     557           0 :                         if (!filename) {
     558           0 :                                 return SQLITE_DENY;
     559             :                         }
     560           0 :                         efree(filename);
     561           0 :                         return SQLITE_OK;
     562             :                 }
     563             : 
     564             :                 default:
     565             :                         /* access allowed */
     566         750 :                         return SQLITE_OK;
     567             :         }
     568             : }
     569             : 
     570         106 : static int pdo_sqlite2_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
     571             : {
     572             :         pdo_sqlite2_db_handle *H;
     573         106 :         int ret = 0;
     574         106 :         long timeout = 60;
     575             :         char *filename;
     576         106 :         char *errmsg = NULL;
     577             : 
     578         106 :         H = pecalloc(1, sizeof(pdo_sqlite2_db_handle), dbh->is_persistent);
     579             : 
     580         106 :         H->einfo.errcode = 0;
     581         106 :         H->einfo.errmsg = NULL;
     582         106 :         dbh->driver_data = H;
     583             : 
     584         106 :         filename = make_filename_safe(dbh->data_source TSRMLS_CC);
     585             : 
     586         106 :         if (!filename) {
     587           0 :                 zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
     588             :                                 "safe_mode/open_basedir prohibits opening %s",
     589             :                                 dbh->data_source);
     590           0 :                 goto cleanup;
     591             :         }
     592             : 
     593         106 :         H->db = sqlite_open(filename, 0666, &errmsg);
     594         106 :         efree(filename);
     595             : 
     596         106 :         if (!H->db) {
     597           0 :                 H->einfo.errcode = SQLITE_ERROR;
     598           0 :                 pdo_sqlite2_error(errmsg, dbh);
     599           0 :                 goto cleanup;
     600             :         }
     601             : 
     602         106 :         sqlite_set_authorizer(H->db, authorizer, NULL);
     603             : 
     604         106 :         if (driver_options) {
     605           0 :                 timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, timeout TSRMLS_CC);
     606             :         }
     607         106 :         sqlite_busy_timeout(H->db, timeout * 1000);
     608             : 
     609         106 :         dbh->alloc_own_columns = 1;
     610         106 :         dbh->max_escaped_char_length = 2;
     611             : 
     612         106 :         ret = 1;
     613             : 
     614             : cleanup:
     615         106 :         dbh->methods = &sqlite2_methods;
     616             : 
     617         106 :         return ret;
     618             : }
     619             : /* }}} */
     620             : 
     621             : pdo_driver_t pdo_sqlite2_driver = {
     622             :         PDO_DRIVER_HEADER(sqlite2),
     623             :         pdo_sqlite2_handle_factory
     624             : };
     625             : 
     626             : 
     627             : 
     628             : #endif
     629             : 
     630             : 
     631             : /*
     632             :  * Local variables:
     633             :  * tab-width: 4
     634             :  * c-basic-offset: 4
     635             :  * End:
     636             :  * vim600: noet sw=4 ts=4 fdm=marker
     637             :  * vim<600: noet sw=4 ts=4
     638             :  */

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:36 +0000 (3 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.