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

Generated by: LCOV version 1.10

Generated at Sat, 29 Jan 2022 07:14:35 +0000 (34 minutes ago)

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