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/mysqlnd - mysqlnd_loaddata.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 70 101 69.3 %
Date: 2014-07-27 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 5                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 2006-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             :   | Authors: Georg Richter <georg@mysql.com>                             |
      16             :   |          Andrey Hristov <andrey@mysql.com>                           |
      17             :   |          Ulf Wendel <uwendel@mysql.com>                              |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : #include "php.h"
      22             : #include "php_globals.h"
      23             : #include "mysqlnd.h"
      24             : #include "mysqlnd_wireprotocol.h"
      25             : #include "mysqlnd_priv.h"
      26             : #include "mysqlnd_debug.h"
      27             : 
      28             : 
      29             : #define ALLOC_CALLBACK_ARGS(a, b, c)\
      30             : if (c) {\
      31             :         a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
      32             :         for (i = b; i < c; i++) {\
      33             :                 a[i] = mnd_emalloc(sizeof(zval *));\
      34             :                 MAKE_STD_ZVAL(*a[i]);\
      35             :         }\
      36             : }
      37             : 
      38             : #define FREE_CALLBACK_ARGS(a, b, c)\
      39             : if (a) {\
      40             :         for (i = b; i < c; i++) {\
      41             :                 zval_ptr_dtor(a[i]);\
      42             :                 mnd_efree(a[i]);\
      43             :         }\
      44             :         mnd_efree(a);\
      45             : }
      46             : 
      47             : /* {{{ mysqlnd_local_infile_init */
      48             : static
      49          12 : int mysqlnd_local_infile_init(void **ptr, char *filename, void **userdata TSRMLS_DC)
      50             : {
      51             :         MYSQLND_INFILE_INFO     *info;
      52          12 :         php_stream_context      *context = NULL;
      53             : 
      54          12 :         DBG_ENTER("mysqlnd_local_infile_init");
      55             : 
      56          12 :         info = ((MYSQLND_INFILE_INFO *)mnd_ecalloc(1, sizeof(MYSQLND_INFILE_INFO)));
      57          12 :         if (!info) {
      58           0 :                 DBG_RETURN(1);
      59             :         }
      60             : 
      61          12 :         *ptr = info;
      62             : 
      63             :         /* check open_basedir */
      64          12 :         if (PG(open_basedir)) {
      65          12 :                 if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) {
      66           0 :                         strcpy(info->error_msg, "open_basedir restriction in effect. Unable to open file");
      67           0 :                         info->error_no = CR_UNKNOWN_ERROR;
      68           0 :                         DBG_RETURN(1);
      69             :                 }
      70             :         }
      71             : 
      72          12 :         info->filename = filename;
      73          12 :         info->fd = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context);
      74             : 
      75          12 :         if (info->fd == NULL) {
      76           1 :                 snprintf((char *)info->error_msg, sizeof(info->error_msg), "Can't find file '%-.64s'.", filename);
      77           1 :                 info->error_no = MYSQLND_EE_FILENOTFOUND;
      78           1 :                 DBG_RETURN(1);
      79             :         }
      80             : 
      81          11 :         DBG_RETURN(0);
      82             : }
      83             : /* }}} */
      84             : 
      85             : 
      86             : /* {{{ mysqlnd_local_infile_read */
      87             : static
      88         898 : int mysqlnd_local_infile_read(void *ptr, char *buf, unsigned int buf_len TSRMLS_DC)
      89             : {
      90         898 :         MYSQLND_INFILE_INFO     *info = (MYSQLND_INFILE_INFO *)ptr;
      91             :         int count;
      92             : 
      93         898 :         DBG_ENTER("mysqlnd_local_infile_read");
      94             : 
      95         898 :         count = (int)php_stream_read(info->fd, buf, buf_len);
      96             : 
      97         898 :         if (count < 0) {
      98           0 :                 strcpy(info->error_msg, "Error reading file");
      99           0 :                 info->error_no = CR_UNKNOWN_ERROR;
     100             :         }
     101             : 
     102         898 :         DBG_RETURN(count);
     103             : }
     104             : /* }}} */
     105             : 
     106             : 
     107             : /* {{{ mysqlnd_local_infile_error */
     108             : static
     109           1 : int     mysqlnd_local_infile_error(void *ptr, char *error_buf, unsigned int error_buf_len TSRMLS_DC)
     110             : {
     111           1 :         MYSQLND_INFILE_INFO     *info = (MYSQLND_INFILE_INFO *)ptr;
     112             : 
     113           1 :         DBG_ENTER("mysqlnd_local_infile_error");
     114             : 
     115           1 :         if (info) {
     116           1 :                 strlcpy(error_buf, info->error_msg, error_buf_len);
     117           1 :                 DBG_INF_FMT("have info, %d", info->error_no);
     118           1 :                 DBG_RETURN(info->error_no);
     119             :         }
     120             : 
     121           0 :         strlcpy(error_buf, "Unknown error", error_buf_len);
     122           0 :         DBG_INF_FMT("no info, %d", CR_UNKNOWN_ERROR);
     123           0 :         DBG_RETURN(CR_UNKNOWN_ERROR);
     124             : }
     125             : /* }}} */
     126             : 
     127             : 
     128             : /* {{{ mysqlnd_local_infile_end */
     129             : static
     130          12 : void mysqlnd_local_infile_end(void *ptr TSRMLS_DC)
     131             : {
     132          12 :         MYSQLND_INFILE_INFO     *info = (MYSQLND_INFILE_INFO *)ptr;
     133             : 
     134          12 :         if (info) {
     135             :                 /* php_stream_close segfaults on NULL */
     136          12 :                 if (info->fd) {
     137          11 :                         php_stream_close(info->fd);
     138          11 :                         info->fd = NULL;
     139             :                 }
     140          12 :                 mnd_efree(info);
     141             :         }
     142          12 : }
     143             : /* }}} */
     144             : 
     145             : 
     146             : /* {{{ mysqlnd_local_infile_default */
     147        3686 : PHPAPI void mysqlnd_local_infile_default(MYSQLND *conn)
     148             : {
     149        3686 :         conn->infile.local_infile_init = mysqlnd_local_infile_init;
     150        3686 :         conn->infile.local_infile_read = mysqlnd_local_infile_read;
     151        3686 :         conn->infile.local_infile_error = mysqlnd_local_infile_error;
     152        3686 :         conn->infile.local_infile_end = mysqlnd_local_infile_end;
     153        3686 : }
     154             : /* }}} */
     155             : 
     156             : /* {{{ mysqlnd_set_local_infile_handler */
     157           0 : PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND * const conn, const char * const funcname)
     158             : {
     159           0 :         if (!conn->infile.callback) {
     160           0 :                 MAKE_STD_ZVAL(conn->infile.callback);
     161             :         } else {
     162           0 :                 zval_dtor(conn->infile.callback);
     163             :         }
     164           0 :         ZVAL_STRING(conn->infile.callback, (char*) funcname, 1);
     165           0 : }
     166             : /* }}} */
     167             : 
     168             : 
     169             : static const char *lost_conn = "Lost connection to MySQL server during LOAD DATA of local file";
     170             : 
     171             : 
     172             : /* {{{ mysqlnd_handle_local_infile */
     173             : enum_func_status
     174          12 : mysqlnd_handle_local_infile(MYSQLND *conn, const char *filename, zend_bool *is_warning TSRMLS_DC)
     175             : {
     176          12 :         char                            *buf = NULL;
     177             :         char                            empty_packet[MYSQLND_HEADER_SIZE];
     178          12 :         enum_func_status        result = FAIL;
     179          12 :         unsigned int            buflen = 4096;
     180          12 :         void                            *info = NULL;
     181             :         int                                     bufsize;
     182             :         size_t                          ret;
     183             :         MYSQLND_INFILE          infile;
     184             : 
     185          12 :         DBG_ENTER("mysqlnd_handle_local_infile");
     186             : 
     187          12 :         if (!(conn->options.flags & CLIENT_LOCAL_FILES)) {
     188           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "LOAD DATA LOCAL INFILE forbidden");
     189             :                 /* write empty packet to server */
     190           0 :                 ret = conn->net->m.send(conn, empty_packet, 0 TSRMLS_CC);
     191           0 :                 *is_warning = TRUE;
     192           0 :                 goto infile_error;
     193             :         }
     194             : 
     195          12 :         infile = conn->infile;
     196             :         /* allocate buffer for reading data */
     197          12 :         buf = (char *)mnd_ecalloc(1, buflen);
     198             : 
     199          12 :         *is_warning = FALSE;
     200             : 
     201             :         /* init handler: allocate read buffer and open file */
     202          12 :         if (infile.local_infile_init(&info, (char *)filename, conn->infile.userdata TSRMLS_CC)) {
     203           1 :                 *is_warning = TRUE;
     204             :                 /* error occured */
     205           1 :                 strcpy(conn->error_info.sqlstate, UNKNOWN_SQLSTATE);
     206           1 :                 conn->error_info.error_no =
     207           1 :                                 infile.local_infile_error(info, conn->error_info.error, sizeof(conn->error_info.error) TSRMLS_CC);
     208             :                 /* write empty packet to server */
     209           1 :                 ret = conn->net->m.send(conn, empty_packet, 0 TSRMLS_CC);
     210           1 :                 goto infile_error;
     211             :         }
     212             : 
     213             :         /* read data */
     214         909 :         while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE TSRMLS_CC)) > 0) {
     215         887 :                 if ((ret = conn->net->m.send(conn, buf, bufsize TSRMLS_CC)) == 0) {
     216           0 :                         DBG_ERR_FMT("Error during read : %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
     217           0 :                         SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
     218           0 :                         goto infile_error;
     219             :                 }
     220             :         }
     221             : 
     222             :         /* send empty packet for eof */
     223          11 :         if ((ret = conn->net->m.send(conn, empty_packet, 0 TSRMLS_CC)) == 0) {
     224           0 :                 SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
     225           0 :                 goto infile_error;
     226             :         }
     227             : 
     228             :         /* error during read occured */
     229          11 :         if (bufsize < 0) {
     230           0 :                 *is_warning = TRUE;
     231           0 :                 DBG_ERR_FMT("Bufsize < 0, warning,  %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
     232           0 :                 strcpy(conn->error_info.sqlstate, UNKNOWN_SQLSTATE);
     233           0 :                 conn->error_info.error_no =
     234           0 :                                 infile.local_infile_error(info, conn->error_info.error, sizeof(conn->error_info.error) TSRMLS_CC);
     235           0 :                 goto infile_error;
     236             :         }
     237             : 
     238          11 :         result = PASS;
     239             : 
     240             : infile_error:
     241             :         /* get response from server and update upsert values */
     242          12 :         if (FAIL == conn->m->simple_command_handle_response(conn, PROT_OK_PACKET, FALSE, COM_QUERY, FALSE TSRMLS_CC)) {
     243           0 :                 result = FAIL;
     244             :         }
     245             : 
     246          12 :         (*conn->infile.local_infile_end)(info TSRMLS_CC);
     247          12 :         if (buf) {
     248          12 :                 mnd_efree(buf);
     249             :         }
     250          12 :         DBG_INF_FMT("%s", result == PASS? "PASS":"FAIL");
     251          12 :         DBG_RETURN(result);
     252             : }
     253             : /* }}} */
     254             : 
     255             : /*
     256             :  * Local variables:
     257             :  * tab-width: 4
     258             :  * c-basic-offset: 4
     259             :  * End:
     260             :  * vim600: noet sw=4 ts=4 fdm=marker
     261             :  * vim<600: noet sw=4 ts=4
     262             :  */

Generated by: LCOV version 1.10

Generated at Sun, 27 Jul 2014 12:58:31 +0000 (45 hours ago)

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