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/mysqli - mysqli_nonapi.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 448 484 92.6 %
Date: 2018-10-10 Functions: 30 30 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | PHP Version 7                                                        |
       4             :   +----------------------------------------------------------------------+
       5             :   | Copyright (c) 1997-2018 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@php.net>                               |
      16             :   |          Andrey Hristov <andrey@php.net>                             |
      17             :   |          Ulf Wendel <uw@php.net>                                     |
      18             :   +----------------------------------------------------------------------+
      19             : 
      20             :   $Id$
      21             : */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include <signal.h>
      28             : 
      29             : #include "php.h"
      30             : #include "php_ini.h"
      31             : #include "ext/standard/info.h"
      32             : #include "zend_smart_str.h"
      33             : #include "php_mysqli_structs.h"
      34             : #include "mysqli_priv.h"
      35             : 
      36             : #define SAFE_STR(a) ((a)?a:"")
      37             : 
      38             : #ifndef zend_parse_parameters_none
      39             : #define zend_parse_parameters_none()    \
      40             :         zend_parse_parameters(ZEND_NUM_ARGS(), "")
      41             : #endif
      42             : 
      43             : /* {{{ php_mysqli_set_error
      44             :  */
      45        1280 : static void php_mysqli_set_error(zend_long mysql_errno, char *mysql_err)
      46             : {
      47        1280 :         MyG(error_no) = mysql_errno;
      48        1280 :         if (MyG(error_msg)) {
      49          19 :                 efree(MyG(error_msg));
      50             :         }
      51        1280 :         if(mysql_err && *mysql_err) {
      52          26 :                 MyG(error_msg) = estrdup(mysql_err);
      53             :         } else {
      54        1254 :                 MyG(error_msg) = NULL;
      55             :         }
      56        1280 : }
      57             : /* }}} */
      58             : 
      59        1313 : void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_connect, zend_bool in_ctor) /* {{{ */
      60             : {
      61        1313 :         MY_MYSQL                        *mysql = NULL;
      62        1313 :         MYSQLI_RESOURCE         *mysqli_resource = NULL;
      63        2626 :         zval                            *object = getThis();
      64        1313 :         char                            *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
      65        1313 :         size_t                                  hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
      66        1313 :         zend_bool                       persistent = FALSE;
      67        1313 :         zend_long                               port = 0, flags = 0;
      68        1313 :         zend_string                     *hash_key = NULL;
      69        1313 :         zend_bool                       new_connection = FALSE;
      70             :         zend_resource           *le;
      71        1313 :         mysqli_plist_entry *plist = NULL;
      72        1313 :         zend_bool                       self_alloced = 0;
      73             : 
      74             : 
      75             : #if !defined(MYSQL_USE_MYSQLND)
      76        1313 :         if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
      77           0 :                 php_error_docref(NULL, E_WARNING,
      78             :                                                 "Headers and client library minor version mismatch. Headers:%d Library:%ld",
      79             :                                                 MYSQL_VERSION_ID, mysql_get_client_version());
      80             :         }
      81             : #endif
      82             : 
      83        2626 :         if (getThis() && !ZEND_NUM_ARGS() && in_ctor) {
      84          16 :                 php_mysqli_init(INTERNAL_FUNCTION_PARAM_PASSTHRU, in_ctor);
      85          16 :                 return;
      86             :         }
      87        1297 :         hostname = username = dbname = passwd = socket = NULL;
      88             : 
      89        1297 :         if (!is_real_connect) {
      90        1150 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ssssls", &hostname, &hostname_len, &username, &username_len,
      91             :                                                                         &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
      92           1 :                         return;
      93             :                 }
      94             : 
      95        1149 :                 if (object && instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry)) {
      96          45 :                         mysqli_resource = (Z_MYSQLI_P(object))->ptr;
      97          45 :                         if (mysqli_resource && mysqli_resource->ptr) {
      98           7 :                                 mysql = (MY_MYSQL*) mysqli_resource->ptr;
      99             :                         }
     100             :                 }
     101        1149 :                 if (!mysql) {
     102        1142 :                         mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL));
     103        1142 :                         self_alloced = 1;
     104             :                 }
     105        1149 :                 flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
     106             :         } else {
     107             :                 /* We have flags too */
     108         294 :                 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|sssslsl", &object, mysqli_link_class_entry,
     109             :                                                                                 &hostname, &hostname_len, &username, &username_len, &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len,
     110             :                                                                                 &flags) == FAILURE) {
     111           8 :                         return;
     112             :                 }
     113             : 
     114         139 :                 mysqli_resource = (Z_MYSQLI_P(object))->ptr;
     115         139 :                 MYSQLI_FETCH_RESOURCE_CONN(mysql, object, MYSQLI_STATUS_INITIALIZED);
     116             : 
     117             :                 /* set some required options */
     118         138 :                 flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
     119             :                 /* remove some insecure options */
     120         138 :                 flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
     121             : #if !defined(MYSQLI_USE_MYSQLND)
     122             :                 if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
     123             :                         flags &= ~CLIENT_LOCAL_FILES;
     124             :                 }
     125             : #endif
     126             :         }
     127             : 
     128        1287 :         if (!socket_len || !socket) {
     129          53 :                 socket = MyG(default_socket);
     130             :         }
     131        1287 :         if (!port){
     132          44 :                 port = MyG(default_port);
     133             :         }
     134        1287 :         if (!passwd) {
     135          26 :                 passwd = MyG(default_pw);
     136          26 :                 passwd_len = strlen(SAFE_STR(passwd));
     137             :         }
     138        1287 :         if (!username){
     139          19 :                 username = MyG(default_user);
     140             :         }
     141        1287 :         if (!hostname || !hostname_len) {
     142          17 :                 hostname = MyG(default_host);
     143             :         }
     144             : 
     145        1432 :         if (mysql->mysql && mysqli_resource &&
     146         145 :                 (mysqli_resource->status > MYSQLI_STATUS_INITIALIZED))
     147             :         {
     148             :                 /* already connected, we should close the connection */
     149          13 :                 php_mysqli_close(mysql, MYSQLI_CLOSE_IMPLICIT, mysqli_resource->status);
     150             :         }
     151             : 
     152        1287 :         if (strlen(SAFE_STR(hostname)) > 2 && !strncasecmp(hostname, "p:", 2)) {
     153          95 :                 hostname += 2;
     154          95 :                 if (!MyG(allow_persistent)) {
     155           0 :                         php_error_docref(NULL, E_WARNING, "Persistent connections are disabled. Downgrading to normal");
     156             :                 } else {
     157          95 :                         mysql->persistent = persistent = TRUE;
     158             : 
     159         285 :                         hash_key = strpprintf(0, "mysqli_%s_%s" ZEND_LONG_FMT "%s%s%s", SAFE_STR(hostname), SAFE_STR(socket),
     160         190 :                                                                 port, SAFE_STR(username), SAFE_STR(dbname),
     161          95 :                                                                 SAFE_STR(passwd));
     162             : 
     163          95 :                         mysql->hash_key = hash_key;
     164             : 
     165             :                         /* check if we can reuse exisiting connection ... */
     166          95 :                         if ((le = zend_hash_find_ptr(&EG(persistent_list), hash_key)) != NULL) {
     167          79 :                                 if (le->type == php_le_pmysqli()) {
     168          79 :                                         plist = (mysqli_plist_entry *) le->ptr;
     169             : 
     170             :                                         do {
     171          79 :                                                 if (zend_ptr_stack_num_elements(&plist->free_links)) {
     172         106 :                                                         mysql->mysql = zend_ptr_stack_pop(&plist->free_links);
     173             : 
     174          53 :                                                         MyG(num_inactive_persistent)--;
     175             :                                                         /* reset variables */
     176             : 
     177             : #ifndef MYSQLI_NO_CHANGE_USER_ON_PCONNECT
     178          53 :                                                         if (!mysqli_change_user_silent(mysql->mysql, username, passwd, dbname, passwd_len)) {
     179             : #else
     180             :                                                         if (!mysql_ping(mysql->mysql)) {
     181             : #endif
     182             : #ifdef MYSQLI_USE_MYSQLND
     183          52 :                                                                 mysqlnd_restart_psession(mysql->mysql);
     184             : #endif
     185          52 :                                                                 MyG(num_active_persistent)++;
     186             : 
     187             :                                                                 /* clear error */
     188          52 :                                                                 php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));                                                              
     189             : 
     190          52 :                                                                 goto end;
     191             :                                                         } else {
     192           1 :                                                                 mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT);
     193           1 :                                                                 mysql->mysql = NULL;
     194             :                                                         }
     195             :                                                 }
     196             :                                         } while (0);
     197             :                                 }
     198             :                         } else {
     199             :                                 zend_resource le;
     200          16 :                                 le.type = php_le_pmysqli();
     201          16 :                                 le.ptr = plist = calloc(1, sizeof(mysqli_plist_entry));
     202             : 
     203          16 :                                 zend_ptr_stack_init_ex(&plist->free_links, 1);
     204          16 :                                 zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(hash_key), ZSTR_LEN(hash_key), &le, sizeof(le));
     205             :                         }
     206             :                 }
     207             :         }
     208        1235 :         if (MyG(max_links) != -1 && MyG(num_links) >= MyG(max_links)) {
     209           5 :                 php_error_docref(NULL, E_WARNING, "Too many open links (" ZEND_LONG_FMT ")", MyG(num_links));
     210           5 :                 goto err;
     211             :         }
     212             : 
     213        1240 :         if (persistent && MyG(max_persistent) != -1 &&
     214          10 :                 (MyG(num_active_persistent) + MyG(num_inactive_persistent))>= MyG(max_persistent))
     215             :         {
     216           2 :                 php_error_docref(NULL, E_WARNING, "Too many open persistent links (" ZEND_LONG_FMT ")",
     217           2 :                                                                 MyG(num_active_persistent) + MyG(num_inactive_persistent));
     218           2 :                 goto err;
     219             :         }
     220        1228 :         if (!mysql->mysql) {
     221             : #if !defined(MYSQLI_USE_MYSQLND)
     222             :                 if (!(mysql->mysql = mysql_init(NULL))) {
     223             : #else
     224        1105 :                 if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent))) {
     225             : #endif
     226           0 :                         goto err;
     227             :                 }
     228        1105 :                 new_connection = TRUE;
     229             :         }
     230             : 
     231             : #ifdef HAVE_EMBEDDED_MYSQLI
     232             :         if (hostname_len) {
     233             :                 unsigned int external=1;
     234             :                 mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external);
     235             :         } else {
     236             :                 mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
     237             :         }
     238             : #endif
     239             : 
     240             : #if !defined(MYSQLI_USE_MYSQLND)
     241             :         /* BC for prior to bug fix #53425 */
     242             :         flags |= CLIENT_MULTI_RESULTS;
     243             : 
     244             :         if (mysql_real_connect(mysql->mysql, hostname, username, passwd, dbname, port, socket, flags) == NULL)
     245             : #else
     246        1228 :         if (mysqlnd_connect(mysql->mysql, hostname, username, passwd, passwd_len, dbname, dbname_len,
     247             :                                                 port, socket, flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA) == NULL)
     248             : #endif
     249             :         {
     250             :                 /* Save error messages - for mysqli_connect_error() & mysqli_connect_errno() */
     251          30 :                 php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));
     252          30 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql),
     253          30 :                                                                                 "%s", mysql_error(mysql->mysql));
     254          30 :                 if (!is_real_connect) {
     255             :                         /* free mysql structure */
     256          19 :                         mysqli_close(mysql->mysql, MYSQLI_CLOSE_DISCONNECTED);
     257          19 :                         mysql->mysql = NULL;
     258             :                 }
     259          30 :                 goto err;
     260             :         }
     261             : 
     262             :         /* clear error */
     263        1198 :         php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql));
     264             : 
     265             : #if !defined(MYSQLI_USE_MYSQLND)
     266             :         mysql->mysql->reconnect = MyG(reconnect);
     267             : #endif
     268             : 
     269        1198 :         mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
     270             : 
     271        1250 : end:
     272        1250 :         if (!mysqli_resource) {
     273        1116 :                 mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     274        1116 :                 mysqli_resource->ptr = (void *)mysql;
     275             :         }
     276        1250 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     277             : 
     278             :         /* store persistent connection */
     279        1250 :         if (persistent && (new_connection || is_real_connect)) {
     280          52 :                 MyG(num_active_persistent)++;
     281             :         }
     282             : 
     283        1250 :         MyG(num_links)++;
     284             : 
     285        1250 :         mysql->multi_query = 0;
     286             : 
     287        1250 :         if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry)) {
     288        1083 :                 MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
     289             :         } else {
     290         167 :                 (Z_MYSQLI_P(object))->ptr = mysqli_resource;
     291             :         }
     292        1250 :         if (!is_real_connect) {
     293        1123 :                 return;
     294             :         } else {
     295         127 :                 RETURN_TRUE;
     296             :         }
     297             : 
     298          37 : err:
     299          37 :         if (mysql->hash_key) {
     300           4 :                 zend_string_release(mysql->hash_key);
     301           4 :                 mysql->hash_key = NULL;
     302           4 :                 mysql->persistent = FALSE;
     303             :         }
     304          37 :         if (!is_real_connect && self_alloced) {
     305          26 :                 efree(mysql);
     306             :         }
     307          37 :         RETVAL_FALSE;
     308             : } /* }}} */
     309             : 
     310             : /* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])
     311             :    Open a connection to a mysql server */
     312        1118 : PHP_FUNCTION(mysqli_connect)
     313             : {
     314        1118 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, FALSE);
     315        1118 : }
     316             : /* }}} */
     317             : 
     318             : /* {{{ proto object mysqli_link_construct()
     319             :   */
     320          48 : PHP_FUNCTION(mysqli_link_construct)
     321             : {
     322          48 :         mysqli_common_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, FALSE, TRUE);
     323          48 : }
     324             : /* }}} */
     325             : 
     326             : /* {{{ proto int mysqli_connect_errno(void)
     327             :    Returns the numerical value of the error message from last connect command */
     328          27 : PHP_FUNCTION(mysqli_connect_errno)
     329             : {
     330          27 :         RETURN_LONG(MyG(error_no));
     331             : }
     332             : /* }}} */
     333             : 
     334             : /* {{{ proto string mysqli_connect_error(void)
     335             :    Returns the text of the error message from previous MySQL operation */
     336          18 : PHP_FUNCTION(mysqli_connect_error)
     337             : {
     338          18 :         if (MyG(error_msg)) {
     339          14 :                 RETURN_STRING(MyG(error_msg));
     340             :         } else {
     341          11 :                 RETURN_NULL();
     342             :         }
     343             : }
     344             : /* }}} */
     345             : 
     346             : /* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype])
     347             :    Fetch a result row as an associative array, a numeric array, or both */
     348       47561 : PHP_FUNCTION(mysqli_fetch_array)
     349             : {
     350       47561 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
     351       47561 : }
     352             : /* }}} */
     353             : 
     354             : /* {{{ proto mixed mysqli_fetch_assoc (object result)
     355             :    Fetch a result row as an associative array */
     356       18257 : PHP_FUNCTION(mysqli_fetch_assoc)
     357             : {
     358       18257 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
     359       18257 : }
     360             : /* }}} */
     361             : 
     362             : /* {{{ proto mixed mysqli_fetch_all (object result [,int resulttype])
     363             :    Fetches all result rows as an associative array, a numeric array, or both */
     364             : #if defined(MYSQLI_USE_MYSQLND)
     365         213 : PHP_FUNCTION(mysqli_fetch_all)
     366             : {
     367             :         MYSQL_RES       *result;
     368             :         zval            *mysql_result;
     369         213 :         zend_long               mode = MYSQLND_FETCH_NUM;
     370             : 
     371         426 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) {
     372           6 :                 return;
     373             :         }
     374         211 :         MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
     375             : 
     376         211 :         if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) {
     377           2 :                 php_error_docref(NULL, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, "
     378             :                                  "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH");
     379           2 :                 RETURN_FALSE;
     380             :         }
     381             : 
     382         209 :         mysqlnd_fetch_all(result, mode, return_value);
     383             : }
     384             : /* }}} */
     385             : 
     386             : /* {{{ proto array mysqli_get_client_stats(void)
     387             :    Returns statistics about the zval cache */
     388          50 : PHP_FUNCTION(mysqli_get_client_stats)
     389             : {
     390          50 :         if (zend_parse_parameters_none() == FAILURE) {
     391           1 :                 return;
     392             :         }
     393          49 :         mysqlnd_get_client_stats(return_value);
     394             : }
     395             : /* }}} */
     396             : 
     397             : /* {{{ proto array mysqli_get_connection_stats(void)
     398             :    Returns statistics about the zval cache */
     399           7 : PHP_FUNCTION(mysqli_get_connection_stats)
     400             : {
     401             :         MY_MYSQL        *mysql;
     402             :         zval            *mysql_link;
     403             : 
     404          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
     405             :                                                                          &mysql_link, mysqli_link_class_entry) == FAILURE) {
     406           4 :                 return;
     407             :         }
     408           5 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     409             : 
     410           5 :         mysqlnd_get_connection_stats(mysql->mysql, return_value);
     411             : }
     412             : #endif
     413             : /* }}} */
     414             : 
     415             : /* {{{ proto mixed mysqli_error_list (object connection)
     416             :    Fetches all client errors */
     417           1 : PHP_FUNCTION(mysqli_error_list)
     418             : {
     419             :         MY_MYSQL        *mysql;
     420             :         zval            *mysql_link;
     421             : 
     422           2 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     423           0 :                 return;
     424             :         }
     425           1 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     426           1 :         array_init(return_value);
     427             : #if defined(MYSQLI_USE_MYSQLND)
     428           1 :         if (mysql->mysql->data->error_info->error_list) {
     429             :                 MYSQLND_ERROR_LIST_ELEMENT * message;
     430             :                 zend_llist_position pos;
     431           2 :                 for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos);
     432             :                          message;
     433           0 :                          message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos))
     434             :                 {
     435             :                         zval single_error;
     436           0 :                         array_init(&single_error);
     437           0 :                         add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
     438           0 :                         add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
     439           0 :                         add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
     440           0 :                         add_next_index_zval(return_value, &single_error);
     441             :                 }
     442             :         }
     443             : #else
     444             :         if (mysql_errno(mysql->mysql)) {
     445             :                 zval single_error;
     446             :                 array_init(&single_error);
     447             :                 add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_errno(mysql->mysql));
     448             :                 add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_sqlstate(mysql->mysql));
     449             :                 add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_error(mysql->mysql));
     450             :                 add_next_index_zval(return_value, &single_error);
     451             :         }
     452             : #endif
     453             : }
     454             : /* }}} */
     455             : 
     456             : /* {{{ proto string mysqli_stmt_error_list(object stmt)
     457             : */
     458           1 : PHP_FUNCTION(mysqli_stmt_error_list)
     459             : {
     460             :         MY_STMT *stmt;
     461             :         zval    *mysql_stmt;
     462             : 
     463           2 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     464           0 :                 return;
     465             :         }
     466           1 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED);
     467           1 :         array_init(return_value);
     468             : #if defined(MYSQLI_USE_MYSQLND)
     469           1 :         if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) {
     470             :                 MYSQLND_ERROR_LIST_ELEMENT * message;
     471             :                 zend_llist_position pos;
     472           2 :                 for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos);
     473             :                          message;
     474           0 :                          message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos))
     475             :                 {
     476             :                         zval single_error;
     477           0 :                         array_init(&single_error);
     478           0 :                         add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, message->error_no);
     479           0 :                         add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, message->sqlstate);
     480           0 :                         add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, message->error);
     481           0 :                         add_next_index_zval(return_value, &single_error);
     482             :                 }
     483             :         }
     484             : #else
     485             :         if (mysql_stmt_errno(stmt->stmt)) {
     486             :                 zval single_error;
     487             :                 array_init(&single_error);
     488             :                 add_assoc_long_ex(&single_error, "errno", sizeof("errno") - 1, mysql_stmt_errno(stmt->stmt));
     489             :                 add_assoc_string_ex(&single_error, "sqlstate", sizeof("sqlstate") - 1, mysql_stmt_sqlstate(stmt->stmt));
     490             :                 add_assoc_string_ex(&single_error, "error", sizeof("error") - 1, mysql_stmt_error(stmt->stmt));
     491             :                 add_next_index_zval(return_value, &single_error);
     492             :         }
     493             : #endif
     494             : }
     495             : /* }}} */
     496             : 
     497             : /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
     498             :    Fetch a result row as an object */
     499          33 : PHP_FUNCTION(mysqli_fetch_object)
     500             : {
     501          33 :         php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
     502          31 : }
     503             : /* }}} */
     504             : 
     505             : /* {{{ proto bool mysqli_multi_query(object link, string query)
     506             :    allows to execute multiple queries  */
     507          28 : PHP_FUNCTION(mysqli_multi_query)
     508             : {
     509             :         MY_MYSQL        *mysql;
     510             :         zval            *mysql_link;
     511          28 :         char            *query = NULL;
     512             :         size_t          query_len;
     513             : 
     514          56 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
     515           2 :                 return;
     516             :         }
     517          26 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     518             : 
     519          25 :         MYSQLI_ENABLE_MQ;
     520          25 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
     521             : #ifndef MYSQLI_USE_MYSQLND
     522             :                 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
     523             :                 unsigned int s_errno;
     524             :                 /* we have to save error information, cause
     525             :                 MYSQLI_DISABLE_MQ will reset error information */
     526             :                 strcpy(s_error, mysql_error(mysql->mysql));
     527             :                 strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
     528             :                 s_errno = mysql_errno(mysql->mysql);
     529             : #else
     530           6 :                 MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info;
     531             : #endif
     532           6 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     533           6 :                 MYSQLI_DISABLE_MQ;
     534             : 
     535             : #ifndef MYSQLI_USE_MYSQLND
     536             :                 /* restore error information */
     537             :                 strcpy(mysql->mysql->net.last_error, s_error);
     538             :                 strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
     539             :                 mysql->mysql->net.last_errno = s_errno;
     540             : #else
     541           6 :                 *mysql->mysql->data->error_info = error_info;
     542             : #endif
     543           6 :                 RETURN_FALSE;
     544             :         }
     545          19 :         RETURN_TRUE;
     546             : }
     547             : /* }}} */
     548             : 
     549             : /* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
     550       19157 : PHP_FUNCTION(mysqli_query)
     551             : {
     552             :         MY_MYSQL                        *mysql;
     553             :         zval                            *mysql_link;
     554             :         MYSQLI_RESOURCE         *mysqli_resource;
     555       19157 :         MYSQL_RES                       *result = NULL;
     556       19157 :         char                            *query = NULL;
     557             :         size_t                          query_len;
     558       19157 :         zend_long                               resultmode = MYSQLI_STORE_RESULT;
     559             : 
     560       38314 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
     561       17683 :                 return;
     562             :         }
     563             : 
     564       19143 :         if (!query_len) {
     565           1 :                 php_error_docref(NULL, E_WARNING, "Empty query");
     566           1 :                 RETURN_FALSE;
     567             :         }
     568             : #ifdef MYSQLI_USE_MYSQLND
     569       19142 :         if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) {
     570             : #else
     571             :         if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) {
     572             : #endif
     573           1 :                 php_error_docref(NULL, E_WARNING, "Invalid value for resultmode");
     574           1 :                 RETURN_FALSE;
     575             :         }
     576             : 
     577       19141 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     578             : 
     579       19131 :         MYSQLI_DISABLE_MQ;
     580             : 
     581             : 
     582             : #ifdef MYSQLI_USE_MYSQLND
     583       19131 :         if (resultmode & MYSQLI_ASYNC) {
     584          29 :                 if (mysqli_async_query(mysql->mysql, query, query_len)) {
     585           2 :                         MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     586           2 :                         RETURN_FALSE;
     587             :                 }
     588          27 :                 mysql->async_result_fetch_type = resultmode & ~MYSQLI_ASYNC;
     589          27 :                 RETURN_TRUE;
     590             :         }
     591             : #endif
     592             : 
     593       19102 :         if (mysql_real_query(mysql->mysql, query, query_len)) {
     594          66 :                 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
     595          66 :                 RETURN_FALSE;
     596             :         }
     597             : 
     598       19036 :         if (!mysql_field_count(mysql->mysql)) {
     599             :                 /* no result set - not a SELECT */
     600       17547 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     601           0 :                         php_mysqli_report_index(query, mysqli_server_status(mysql->mysql));
     602             :                 }
     603       17547 :                 RETURN_TRUE;
     604             :         }
     605             : 
     606             : #ifdef MYSQLI_USE_MYSQLND
     607        1489 :         switch (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) {
     608             : #else
     609             :         switch (resultmode & ~MYSQLI_ASYNC) {
     610             : #endif
     611        1476 :                 case MYSQLI_STORE_RESULT:
     612             : #ifdef MYSQLI_USE_MYSQLND
     613        1476 :                         if (resultmode & MYSQLI_STORE_RESULT_COPY_DATA) {
     614           0 :                                 result = mysqlnd_store_result_ofs(mysql->mysql);
     615             :                         } else
     616             : #endif
     617        1476 :                                 result = mysql_store_result(mysql->mysql);
     618        1476 :                         break;
     619          13 :                 case MYSQLI_USE_RESULT:
     620          13 :                         result = mysql_use_result(mysql->mysql);
     621          13 :                         break;
     622             :         }
     623        1489 :         if (!result) {
     624           1 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql),
     625           1 :                                                                                 "%s", mysql_error(mysql->mysql));
     626           1 :                 RETURN_FALSE;
     627             :         }
     628             : 
     629        1488 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     630           2 :                 php_mysqli_report_index(query, mysqli_server_status(mysql->mysql));
     631             :         }
     632             : 
     633        1488 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     634        1488 :         mysqli_resource->ptr = (void *)result;
     635        1488 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     636        1488 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     637             : }
     638             : /* }}} */
     639             : 
     640             : #if defined(MYSQLI_USE_MYSQLND)
     641             : #include "php_network.h"
     642             : /* {{{ mysqlnd_zval_array_to_mysqlnd_array functions */
     643          65 : static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_array)
     644             : {
     645             :         zval *elem;
     646          65 :         int i = 0, current = 0;
     647             : 
     648          65 :         if (Z_TYPE_P(in_array) != IS_ARRAY) {
     649           0 :                 return 0;
     650             :         }
     651          65 :         *out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *));
     652         311 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_array), elem) {
     653         123 :                 i++;
     654         246 :                 if (Z_TYPE_P(elem) != IS_OBJECT ||
     655         123 :                         !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) {
     656           0 :                         php_error_docref(NULL, E_WARNING, "Parameter %d not a mysqli object", i);
     657             :                 } else {
     658             :                         MY_MYSQL *mysql;
     659             :                         MYSQLI_RESOURCE *my_res;
     660         123 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     661         123 :                         if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
     662           2 :                                 php_error_docref(NULL, E_WARNING, "[%d] Couldn't fetch %s", i, ZSTR_VAL(intern->zo.ce->name));
     663           2 :                                 continue;
     664             :                         }
     665         121 :                         mysql = (MY_MYSQL*) my_res->ptr;
     666         121 :                         if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) {
     667           0 :                                 php_error_docref(NULL, E_WARNING, "Invalid object %d or resource %s", i, ZSTR_VAL(intern->zo.ce->name));
     668           0 :                                 continue;
     669             :                         }
     670         121 :                         (*out_array)[current++] = mysql->mysql;
     671             :                 }
     672             :         } ZEND_HASH_FOREACH_END();
     673          65 :         return 0;
     674             : }
     675             : /* }}} */
     676             : 
     677             : /* {{{ mysqlnd_zval_array_from_mysqlnd_array */
     678          65 : static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_array)
     679             : {
     680          65 :         MYSQLND **p = in_array;
     681             :         zval dest_array;
     682             :         zval *elem, *dest_elem;
     683          65 :         int ret = 0, i = 0;
     684             : 
     685          65 :         array_init_size(&dest_array, zend_hash_num_elements(Z_ARRVAL_P(out_array)));
     686             : 
     687         311 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(out_array), elem) {
     688         123 :                 i++;
     689         246 :                 if (Z_TYPE_P(elem) != IS_OBJECT ||
     690         123 :                                 !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) {
     691           0 :                         continue;
     692             :                 }
     693             :                 {
     694             :                         MY_MYSQL *mysql;
     695             :                         MYSQLI_RESOURCE *my_res;
     696         123 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     697         123 :                         if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
     698           2 :                                 php_error_docref(NULL, E_WARNING, "[%d] Couldn't fetch %s", i, ZSTR_VAL(intern->zo.ce->name));
     699           2 :                                 continue;
     700             :                         }
     701         121 :                         mysql = (MY_MYSQL *) my_res->ptr;
     702         121 :                         if (mysql->mysql == *p) {
     703          28 :                                 dest_elem = zend_hash_next_index_insert(Z_ARRVAL(dest_array), elem);
     704          28 :                                 if (dest_elem) {
     705          28 :                                         zval_add_ref(dest_elem);
     706             :                                 }
     707          28 :                                 ret++;
     708          28 :                                 p++;
     709             :                         }
     710             :                 }
     711             :         } ZEND_HASH_FOREACH_END();
     712             : 
     713             :         /* destroy old array and add new one */
     714          65 :         zval_ptr_dtor(out_array);
     715          65 :         ZVAL_COPY_VALUE(out_array, &dest_array);
     716             : 
     717          65 :         return 0;
     718             : }
     719             : /* }}} */
     720             : 
     721             : /* {{{ mysqlnd_dont_poll_zval_array_from_mysqlnd_array */
     722          33 : static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *in_zval_array, zval *out_array)
     723             : {
     724          33 :         MYSQLND **p = in_array;
     725             :         zval proxy, *elem, *dest_elem;
     726          33 :         int ret = 0;
     727             : 
     728          33 :         array_init(&proxy);
     729          33 :         if (in_array) {
     730          76 :                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_zval_array), elem) {
     731             :                         MY_MYSQL *mysql;
     732          29 :                         mysqli_object *intern = Z_MYSQLI_P(elem);
     733          29 :                         mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)intern->ptr)->ptr;
     734          29 :                         if (mysql->mysql == *p) {
     735          20 :                                 dest_elem = zend_hash_next_index_insert(Z_ARRVAL(proxy), elem);
     736          20 :                                 if (dest_elem) {
     737          20 :                                         zval_add_ref(dest_elem);
     738             :                                 }
     739          20 :                                 ret++;
     740          20 :                                 p++;
     741             :                         }
     742             :                 } ZEND_HASH_FOREACH_END();
     743             :         }
     744             : 
     745             :         /* destroy old array and add new one */
     746          33 :         zval_ptr_dtor(out_array);
     747          33 :         ZVAL_COPY_VALUE(out_array, &proxy);
     748             : 
     749          33 :         return 0;
     750             : }
     751             : /* }}} */
     752             : 
     753             : /* {{{ proto int mysqli_poll(array read, array write, array error, long sec [, long usec]) U
     754             :    Poll connections */
     755          42 : PHP_FUNCTION(mysqli_poll)
     756             : {
     757             :         zval                    *r_array, *e_array, *dont_poll_array;
     758          42 :         MYSQLND                 **new_r_array = NULL, **new_e_array = NULL, **new_dont_poll_array = NULL;
     759          42 :         zend_long                       sec = 0, usec = 0;
     760             :         enum_func_status ret;
     761             :         int                     desc_num;
     762             : 
     763          42 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) {
     764           6 :                 return;
     765             :         }
     766          36 :         if (sec < 0 || usec < 0) {
     767           2 :                 php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec");
     768           2 :                 RETURN_FALSE;
     769             :         }
     770             : 
     771          34 :         if (!r_array && !e_array) {
     772           1 :                 php_error_docref(NULL, E_WARNING, "No stream arrays were passed");
     773           1 :                 RETURN_FALSE;
     774             :         }
     775             : 
     776          33 :         if (r_array != NULL) {
     777          33 :                 mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array);
     778             :         }
     779          33 :         if (e_array != NULL) {
     780          32 :                 mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array);
     781             :         }
     782             : 
     783          33 :         ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num);
     784             : 
     785          33 :         mysqlnd_dont_poll_zval_array_from_mysqlnd_array(r_array != NULL ? new_dont_poll_array:NULL, r_array, dont_poll_array);
     786             : 
     787          33 :         if (r_array != NULL) {
     788          33 :                 mysqlnd_zval_array_from_mysqlnd_array(new_r_array, r_array);
     789             :         }
     790          33 :         if (e_array != NULL) {
     791          32 :                 mysqlnd_zval_array_from_mysqlnd_array(new_e_array, e_array);
     792             :         }
     793             : 
     794          33 :         if (new_dont_poll_array) {
     795          18 :                 efree(new_dont_poll_array);
     796             :         }
     797          33 :         if (new_r_array) {
     798          33 :                 efree(new_r_array);
     799             :         }
     800          33 :         if (new_e_array) {
     801          32 :                 efree(new_e_array);
     802             :         }
     803          33 :         if (ret == PASS) {
     804          29 :                 RETURN_LONG(desc_num);
     805             :         } else {
     806           4 :                 RETURN_FALSE;
     807             :         }
     808             : }
     809             : /* }}} */
     810             : 
     811             : /* {{{ proto int mysqli_reap_async_query(object link) U
     812             :    Poll connections */
     813          29 : PHP_FUNCTION(mysqli_reap_async_query)
     814             : {
     815             :         MY_MYSQL                *mysql;
     816             :         zval                    *mysql_link;
     817             :         MYSQLI_RESOURCE         *mysqli_resource;
     818          29 :         MYSQL_RES                       *result = NULL;
     819             : 
     820          58 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     821          17 :                 return;
     822             :         }
     823             : 
     824          26 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     825             : 
     826          26 :         if (FAIL == mysqlnd_reap_async_query(mysql->mysql)) {
     827           4 :                 RETURN_FALSE;
     828             :         }
     829             : 
     830          22 :         if (!mysql_field_count(mysql->mysql)) {
     831             :                 /* no result set - not a SELECT */
     832           7 :                 if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     833             : /*                      php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql)); */
     834             :                 }
     835           7 :                 RETURN_TRUE;
     836             :         }
     837             : 
     838          15 :         switch (mysql->async_result_fetch_type) {
     839           1 :                 case MYSQLI_STORE_RESULT:
     840           1 :                         result = mysql_store_result(mysql->mysql);
     841           1 :                         break;
     842          14 :                 case MYSQLI_USE_RESULT:
     843          14 :                         result = mysql_use_result(mysql->mysql);
     844          14 :                         break;
     845             :         }
     846             : 
     847          15 :         if (!result) {
     848           0 :                 php_mysqli_throw_sql_exception((char *)mysql_sqlstate(mysql->mysql), mysql_errno(mysql->mysql),
     849           0 :                                                                                 "%s", mysql_error(mysql->mysql));
     850           0 :                 RETURN_FALSE;
     851             :         }
     852             : 
     853          15 :         if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
     854             : /*              php_mysqli_report_index("n/a", mysqli_server_status(mysql->mysql)); */
     855             :         }
     856             : 
     857          15 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     858          15 :         mysqli_resource->ptr = (void *)result;
     859          15 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     860          15 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     861             : }
     862             : /* }}} */
     863             : 
     864             : /* {{{ proto object mysqli_stmt_get_result(object link) U
     865             :    Buffer result set on client */
     866         591 : PHP_FUNCTION(mysqli_stmt_get_result)
     867             : {
     868             :         MYSQL_RES               *result;
     869             :         MYSQLI_RESOURCE *mysqli_resource;
     870             :         MY_STMT                 *stmt;
     871             :         zval                    *mysql_stmt;
     872             : 
     873        1182 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
     874          18 :                 return;
     875             :         }
     876         586 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID);
     877             : 
     878         584 :         if (!(result = mysqlnd_stmt_get_result(stmt->stmt))) {
     879           6 :                 MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
     880           6 :                 RETURN_FALSE;
     881             :         }
     882             : 
     883         578 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     884         578 :         mysqli_resource->ptr = (void *)result;
     885         578 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     886         578 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
     887             : }
     888             : /* }}} */
     889             : #endif
     890             : 
     891             : /* {{{ proto object mysqli_get_warnings(object link) */
     892           5 : PHP_FUNCTION(mysqli_get_warnings)
     893             : {
     894             :         MY_MYSQL                        *mysql;
     895             :         zval                            *mysql_link;
     896             :         MYSQLI_RESOURCE         *mysqli_resource;
     897             :         MYSQLI_WARNING          *w;
     898             : 
     899          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     900           0 :                 return;
     901             :         }
     902           5 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     903             : 
     904           5 :         if (mysql_warning_count(mysql->mysql)) {
     905             : #ifdef MYSQLI_USE_MYSQLND
     906           5 :                 w = php_get_warnings(mysql->mysql->data);
     907             : #else
     908             :                 w = php_get_warnings(mysql->mysql);
     909             : #endif
     910             :         } else {
     911           0 :                 RETURN_FALSE;
     912             :         }
     913           5 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     914           5 :         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
     915           5 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     916           5 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
     917             : }
     918             : /* }}} */
     919             : 
     920             : /* {{{ proto object mysqli_stmt_get_warnings(object link) */
     921           7 : PHP_FUNCTION(mysqli_stmt_get_warnings)
     922             : {
     923             :         MY_STMT                         *stmt;
     924             :         zval                            *stmt_link;
     925             :         MYSQLI_RESOURCE         *mysqli_resource;
     926             :         MYSQLI_WARNING          *w;
     927             : 
     928          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) {
     929           8 :                 return;
     930             :         }
     931           5 :         MYSQLI_FETCH_RESOURCE_STMT(stmt, stmt_link, MYSQLI_STATUS_VALID);
     932             : 
     933           3 :         if (mysqli_stmt_warning_count(stmt->stmt)) {
     934           1 :                 w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt));
     935             :         } else {
     936           2 :                 RETURN_FALSE;
     937             :         }
     938           1 :         mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
     939           1 :         mysqli_resource->ptr = mysqli_resource->info = (void *)w;
     940           1 :         mysqli_resource->status = MYSQLI_STATUS_VALID;
     941           1 :         MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
     942             : }
     943             : /* }}} */
     944             : 
     945             : #ifdef HAVE_MYSQLI_SET_CHARSET
     946             : /* {{{ proto bool mysqli_set_charset(object link, string csname)
     947             :    sets client character set */
     948         103 : PHP_FUNCTION(mysqli_set_charset)
     949             : {
     950             :         MY_MYSQL        *mysql;
     951             :         zval            *mysql_link;
     952             :         char            *cs_name;
     953             :         size_t          csname_len;
     954             : 
     955         206 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &csname_len) == FAILURE) {
     956           4 :                 return;
     957             :         }
     958          99 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     959             : 
     960          97 :         if (mysql_set_character_set(mysql->mysql, cs_name)) {
     961           2 :                 RETURN_FALSE;
     962             :         }
     963          95 :         RETURN_TRUE;
     964             : }
     965             : /* }}} */
     966             : #endif
     967             : 
     968             : #ifdef HAVE_MYSQLI_GET_CHARSET
     969             : /* {{{ proto object mysqli_get_charset(object link) U
     970             :    returns a character set object */
     971          10 : PHP_FUNCTION(mysqli_get_charset)
     972             : {
     973             :         MY_MYSQL                                *mysql;
     974             :         zval                                    *mysql_link;
     975          10 :         const char                              *name = NULL, *collation = NULL, *dir = NULL, *comment = NULL;
     976             :         uint                                    minlength, maxlength, number, state;
     977             : #if !defined(MYSQLI_USE_MYSQLND)
     978             :         MY_CHARSET_INFO                 cs;
     979             : #else
     980             :         const MYSQLND_CHARSET   *cs;
     981             : #endif
     982             : 
     983          20 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
     984           5 :                 return;
     985             :         }
     986           8 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
     987             : 
     988             : 
     989             : #if !defined(MYSQLI_USE_MYSQLND)
     990             :         mysql_get_character_set_info(mysql->mysql, &cs);
     991             :         name = (char *)cs.csname;
     992             :         collation = (char *)cs.name;
     993             :         dir = (char *)cs.dir;
     994             :         minlength = cs.mbminlen;
     995             :         maxlength = cs.mbmaxlen;
     996             :         number = cs.number;
     997             :         state = cs.state;
     998             :         comment = cs.comment;
     999             : #else
    1000           7 :         cs = mysql->mysql->data->charset;
    1001           7 :         if (!cs) {
    1002           0 :                 php_error_docref(NULL, E_WARNING, "The connection has no charset associated");
    1003           0 :                 RETURN_NULL();
    1004             :         }
    1005           7 :         name = cs->name;
    1006           7 :         collation = cs->collation;
    1007           7 :         minlength = cs->char_minlen;
    1008           7 :         maxlength = cs->char_maxlen;
    1009           7 :         number = cs->nr;
    1010           7 :         comment = cs->comment;
    1011           7 :         state = 1;      /* all charsets are compiled in */
    1012             : #endif
    1013           7 :         object_init(return_value);
    1014             : 
    1015           7 :         add_property_string(return_value, "charset", (name) ? (char *)name : "");
    1016           7 :         add_property_string(return_value, "collation",(collation) ? (char *)collation : "");
    1017           7 :         add_property_string(return_value, "dir", (dir) ? (char *)dir : "");
    1018           7 :         add_property_long(return_value, "min_length", minlength);
    1019           7 :         add_property_long(return_value, "max_length", maxlength);
    1020           7 :         add_property_long(return_value, "number", number);
    1021           7 :         add_property_long(return_value, "state", state);
    1022           7 :         add_property_string(return_value, "comment", (comment) ? (char *)comment : "");
    1023             : }
    1024             : /* }}} */
    1025             : #endif
    1026             : 
    1027             : #if !defined(MYSQLI_USE_MYSQLND)
    1028             : extern char * mysqli_escape_string_for_tx_name_in_comment(const char * const name);
    1029             : 
    1030             : /* {{{ proto bool mysqli_begin_transaction_libmysql */
    1031             : static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name)
    1032             : {
    1033             :         int ret;
    1034             :         zend_bool err = FALSE;
    1035             :         smart_str tmp_str = {0};
    1036             :         if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
    1037             :                 if (tmp_str.s) {
    1038             :                         smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1039             :                 }
    1040             :                 smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
    1041             :         }
    1042             :         if (mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY)) {
    1043             :                 if (mysql_get_server_version(conn) < 50605L) {
    1044             :                         php_error_docref(NULL, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
    1045             :                         err = TRUE;
    1046             :                 } else if (mode & TRANS_START_READ_WRITE) {
    1047             :                         if (tmp_str.s) {
    1048             :                                 smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1049             :                         }
    1050             :                         smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
    1051             :                 } else if (mode & TRANS_START_READ_ONLY) {
    1052             :                         if (tmp_str.s) {
    1053             :                                 smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
    1054             :                         }
    1055             :                         smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
    1056             :                 }
    1057             :         }
    1058             :         smart_str_0(&tmp_str);
    1059             : 
    1060             :         if (err == FALSE){
    1061             :                 char * name_esc = mysqli_escape_string_for_tx_name_in_comment(name);
    1062             :                 char * query;
    1063             :                 unsigned int query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
    1064             :                                                                                   name_esc? name_esc:"", tmp_str.s? ZSTR_VAL(tmp_str.s):"");
    1065             : 
    1066             :                 smart_str_free(&tmp_str);
    1067             :                 if (name_esc) {
    1068             :                         efree(name_esc);
    1069             :                 }
    1070             : 
    1071             :                 ret = mysql_real_query(conn, query, query_len);
    1072             :                 efree(query);
    1073             :         }
    1074             :         return ret;
    1075             : }
    1076             : /* }}} */
    1077             : #endif
    1078             : 
    1079             : /* {{{ proto bool mysqli_begin_transaction(object link, [int flags [, string name]])
    1080             :    Starts a transaction */
    1081           9 : PHP_FUNCTION(mysqli_begin_transaction)
    1082             : {
    1083             :         MY_MYSQL        *mysql;
    1084             :         zval            *mysql_link;
    1085           9 :         zend_long               flags = TRANS_START_NO_OPT;
    1086           9 :         char *          name = NULL;
    1087           9 :         size_t                  name_len = -1;
    1088           9 :         zend_bool       err = FALSE;
    1089             : 
    1090          18 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
    1091           6 :                 return;
    1092             :         }
    1093           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1094           3 :         if (flags < 0) {
    1095           1 :                 php_error_docref(NULL, E_WARNING, "Invalid value for parameter flags (" ZEND_LONG_FMT ")", flags);
    1096           1 :                 err = TRUE;
    1097             :         }
    1098           3 :         if (!name_len) {
    1099           0 :                 php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
    1100           0 :                 err = TRUE;
    1101             :         }
    1102           3 :         if (TRUE == err) {
    1103           1 :                 RETURN_FALSE;
    1104             :         }
    1105             : 
    1106             : #if !defined(MYSQLI_USE_MYSQLND)
    1107             :         if (mysqli_begin_transaction_libmysql(mysql->mysql, flags, name)) {
    1108             :                 RETURN_FALSE;
    1109             :         }
    1110             : #else
    1111           2 :         if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) {
    1112           0 :                 RETURN_FALSE;
    1113             :         }
    1114             : #endif
    1115           2 :         RETURN_TRUE;
    1116             : }
    1117             : /* }}} */
    1118             : 
    1119             : #if !defined(MYSQLI_USE_MYSQLND)
    1120             : /* {{{ proto bool mysqli_savepoint_libmysql */
    1121             : static int mysqli_savepoint_libmysql(MYSQL * conn, const char * const name, zend_bool release)
    1122             : {
    1123             :         int ret;
    1124             :         char * query;
    1125             :         unsigned int query_len = spprintf(&query, 0, release? "RELEASE SAVEPOINT `%s`":"SAVEPOINT `%s`", name);
    1126             :         ret = mysql_real_query(conn, query, query_len);
    1127             :         efree(query);
    1128             :         return ret;
    1129             : }
    1130             : /* }}} */
    1131             : #endif
    1132             : 
    1133             : /* {{{ proto bool mysqli_savepoint(object link, string name)
    1134             :    Starts a transaction */
    1135           7 : PHP_FUNCTION(mysqli_savepoint)
    1136             : {
    1137             :         MY_MYSQL        *mysql;
    1138             :         zval            *mysql_link;
    1139           7 :         char *          name = NULL;
    1140           7 :         size_t                  name_len = -1;
    1141             : 
    1142          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
    1143           4 :                 return;
    1144             :         }
    1145           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1146           3 :         if (!name || !name_len) {
    1147           1 :                 php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
    1148           1 :                 RETURN_FALSE;
    1149             :         }
    1150             : 
    1151             : #if !defined(MYSQLI_USE_MYSQLND)
    1152             :         if (mysqli_savepoint_libmysql(mysql->mysql, name, FALSE)) {
    1153             : #else
    1154           2 :         if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
    1155             : #endif
    1156           0 :                 RETURN_FALSE;
    1157             :         }
    1158           2 :         RETURN_TRUE;
    1159             : }
    1160             : /* }}} */
    1161             : 
    1162             : /* {{{ proto bool mysqli_release_savepoint(object link, string name)
    1163             :    Starts a transaction */
    1164           7 : PHP_FUNCTION(mysqli_release_savepoint)
    1165             : {
    1166             :         MY_MYSQL        *mysql;
    1167             :         zval            *mysql_link;
    1168           7 :         char *          name = NULL;
    1169           7 :         size_t                  name_len = -1;
    1170             : 
    1171          14 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
    1172           4 :                 return;
    1173             :         }
    1174           3 :         MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
    1175           3 :         if (!name || !name_len) {
    1176           1 :                 php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
    1177           1 :                 RETURN_FALSE;
    1178             :         }
    1179             : #if !defined(MYSQLI_USE_MYSQLND)
    1180             :         if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) {
    1181             : #else
    1182           2 :         if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
    1183             : #endif
    1184           0 :                 RETURN_FALSE;
    1185             :         }
    1186           2 :         RETURN_TRUE;
    1187             : }
    1188             : /* }}} */
    1189             : 
    1190             : /* {{{ proto bool mysqli_get_links_stats()
    1191             :    Returns information about open and cached links */
    1192           7 : PHP_FUNCTION(mysqli_get_links_stats)
    1193             : {
    1194           7 :         if (ZEND_NUM_ARGS()) {
    1195           1 :                 php_error_docref(NULL, E_WARNING, "no parameters expected");
    1196           1 :                 return;
    1197             :         }
    1198           6 :         array_init(return_value);
    1199           6 :         add_assoc_long_ex(return_value, "total", sizeof("total") - 1, MyG(num_links));
    1200           6 :         add_assoc_long_ex(return_value, "active_plinks", sizeof("active_plinks") - 1, MyG(num_active_persistent));
    1201           6 :         add_assoc_long_ex(return_value, "cached_plinks", sizeof("cached_plinks") - 1, MyG(num_inactive_persistent));
    1202             : }
    1203             : /* }}} */
    1204             : 
    1205             : 
    1206             : /*
    1207             :  * Local variables:
    1208             :  * tab-width: 4
    1209             :  * c-basic-offset: 4
    1210             :  * End:
    1211             :  * vim600: noet sw=4 ts=4 fdm=marker
    1212             :  * vim<600: noet sw=4 ts=4
    1213             :  */

Generated by: LCOV version 1.10

Generated at Wed, 10 Oct 2018 12:41:34 +0000 (11 days ago)

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