You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

637 lines
15 KiB

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