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

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:07 +0000 (28 days ago)

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