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: 75 96 78.1 %
Date: 2016-06-25 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 25 Jun 2016 07:08:59 +0000 (5 days ago)

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