]> granicus.if.org Git - php/commitdiff
Use stack-allocated packets.
authorDmitry Stogov <dmitry@zend.com>
Tue, 14 Nov 2017 12:10:27 +0000 (15:10 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 14 Nov 2017 12:10:27 +0000 (15:10 +0300)
ext/mysqlnd/mysqlnd_auth.c
ext/mysqlnd/mysqlnd_commands.c
ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_result_meta.c
ext/mysqlnd/mysqlnd_structs.h
ext/mysqlnd/mysqlnd_wireprotocol.c
ext/mysqlnd/mysqlnd_wireprotocol.h

index 5c295cbfc123a75efff0986add44417f9def0fd0..52cc55798f0a6ea8d78c04c5834196f6afbb52ac 100644 (file)
@@ -251,100 +251,97 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
 {
        enum_func_status ret = FAIL;
        const MYSQLND_CHARSET * charset = NULL;
-       MYSQLND_PACKET_CHANGE_AUTH_RESPONSE * change_auth_resp_packet = NULL;
-       MYSQLND_PACKET_AUTH_RESPONSE * auth_resp_packet = NULL;
-       MYSQLND_PACKET_AUTH * auth_packet = NULL;
+       MYSQLND_PACKET_AUTH_RESPONSE auth_resp_packet;
 
        DBG_ENTER("mysqlnd_auth_handshake");
 
-       auth_resp_packet = conn->payload_decoder_factory->m.get_auth_response_packet(conn->payload_decoder_factory, FALSE);
-
-       if (!auth_resp_packet) {
-               SET_OOM_ERROR(conn->error_info);
-               goto end;
-       }
+       conn->payload_decoder_factory->m.init_auth_response_packet(&auth_resp_packet);
 
        if (use_full_blown_auth_packet != TRUE) {
-               change_auth_resp_packet = conn->payload_decoder_factory->m.get_change_auth_response_packet(conn->payload_decoder_factory, FALSE);
-               if (!change_auth_resp_packet) {
-                       SET_OOM_ERROR(conn->error_info);
-                       goto end;
-               }
+               MYSQLND_PACKET_CHANGE_AUTH_RESPONSE change_auth_resp_packet;
+
+               conn->payload_decoder_factory->m.init_change_auth_response_packet(&change_auth_resp_packet);
 
-               change_auth_resp_packet->auth_data = auth_plugin_data;
-               change_auth_resp_packet->auth_data_len = auth_plugin_data_len;
+               change_auth_resp_packet.auth_data = auth_plugin_data;
+               change_auth_resp_packet.auth_data_len = auth_plugin_data_len;
 
-               if (!PACKET_WRITE(change_auth_resp_packet)) {
+               if (!PACKET_WRITE(conn, &change_auth_resp_packet)) {
                        SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
                        SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
+                       PACKET_FREE(&change_auth_resp_packet);
                        goto end;
                }
+               PACKET_FREE(&change_auth_resp_packet);
        } else {
-               auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE);
+               MYSQLND_PACKET_AUTH auth_packet;
 
-               auth_packet->client_flags = mysql_flags;
-               auth_packet->max_packet_size = session_options->max_allowed_packet;
+               conn->payload_decoder_factory->m.init_auth_packet(&auth_packet);
+
+               auth_packet.client_flags = mysql_flags;
+               auth_packet.max_packet_size = session_options->max_allowed_packet;
                if (session_options->charset_name && (charset = mysqlnd_find_charset_name(session_options->charset_name))) {
-                       auth_packet->charset_no = charset->nr;
+                       auth_packet.charset_no  = charset->nr;
                } else {
-                       auth_packet->charset_no = server_charset_no;
+                       auth_packet.charset_no  = server_charset_no;
                }
 
-               auth_packet->send_auth_data = TRUE;
-               auth_packet->user               = user;
-               auth_packet->db                 = db;
-               auth_packet->db_len             = db_len;
+               auth_packet.send_auth_data = TRUE;
+               auth_packet.user                = user;
+               auth_packet.db                  = db;
+               auth_packet.db_len              = db_len;
 
-               auth_packet->auth_data = auth_plugin_data;
-               auth_packet->auth_data_len = auth_plugin_data_len;
-               auth_packet->auth_plugin_name = auth_protocol;
+               auth_packet.auth_data = auth_plugin_data;
+               auth_packet.auth_data_len = auth_plugin_data_len;
+               auth_packet.auth_plugin_name = auth_protocol;
 
                if (conn->server_capabilities & CLIENT_CONNECT_ATTRS) {
-                       auth_packet->connect_attr = conn->options->connect_attr;
+                       auth_packet.connect_attr = conn->options->connect_attr;
                }
 
-               if (!PACKET_WRITE(auth_packet)) {
+               if (!PACKET_WRITE(conn, &auth_packet)) {
+                       PACKET_FREE(&auth_packet);
                        goto end;
                }
-       }
-       if (use_full_blown_auth_packet == TRUE) {
-               conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no);
+
+               if (use_full_blown_auth_packet == TRUE) {
+                       conn->charset = mysqlnd_find_charset_nr(auth_packet.charset_no);
+               }
+
+               PACKET_FREE(&auth_packet);
        }
 
-       if (FAIL == PACKET_READ(auth_resp_packet) || auth_resp_packet->response_code >= 0xFE) {
-               if (auth_resp_packet->response_code == 0xFE) {
+       if (FAIL == PACKET_READ(conn, &auth_resp_packet) || auth_resp_packet.response_code >= 0xFE) {
+               if (auth_resp_packet.response_code == 0xFE) {
                        /* old authentication with new server  !*/
-                       if (!auth_resp_packet->new_auth_protocol) {
+                       if (!auth_resp_packet.new_auth_protocol) {
                                DBG_ERR(mysqlnd_old_passwd);
                                SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
                        } else {
-                               *switch_to_auth_protocol = mnd_pestrndup(auth_resp_packet->new_auth_protocol, auth_resp_packet->new_auth_protocol_len, FALSE);
-                               *switch_to_auth_protocol_len = auth_resp_packet->new_auth_protocol_len;
-                               if (auth_resp_packet->new_auth_protocol_data) {
-                                       *switch_to_auth_protocol_data_len = auth_resp_packet->new_auth_protocol_data_len;
+                               *switch_to_auth_protocol = mnd_pestrndup(auth_resp_packet.new_auth_protocol, auth_resp_packet.new_auth_protocol_len, FALSE);
+                               *switch_to_auth_protocol_len = auth_resp_packet.new_auth_protocol_len;
+                               if (auth_resp_packet.new_auth_protocol_data) {
+                                       *switch_to_auth_protocol_data_len = auth_resp_packet.new_auth_protocol_data_len;
                                        *switch_to_auth_protocol_data = mnd_emalloc(*switch_to_auth_protocol_data_len);
-                                       memcpy(*switch_to_auth_protocol_data, auth_resp_packet->new_auth_protocol_data, *switch_to_auth_protocol_data_len);
+                                       memcpy(*switch_to_auth_protocol_data, auth_resp_packet.new_auth_protocol_data, *switch_to_auth_protocol_data_len);
                                } else {
                                        *switch_to_auth_protocol_data = NULL;
                                        *switch_to_auth_protocol_data_len = 0;
                                }
                        }
-               } else if (auth_resp_packet->response_code == 0xFF) {
-                       if (auth_resp_packet->sqlstate[0]) {
-                               strlcpy(conn->error_info->sqlstate, auth_resp_packet->sqlstate, sizeof(conn->error_info->sqlstate));
-                               DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet->error_no, auth_resp_packet->sqlstate, auth_resp_packet->error);
+               } else if (auth_resp_packet.response_code == 0xFF) {
+                       if (auth_resp_packet.sqlstate[0]) {
+                               strlcpy(conn->error_info->sqlstate, auth_resp_packet.sqlstate, sizeof(conn->error_info->sqlstate));
+                               DBG_ERR_FMT("ERROR:%u [SQLSTATE:%s] %s", auth_resp_packet.error_no, auth_resp_packet.sqlstate, auth_resp_packet.error);
                        }
-                       SET_CLIENT_ERROR(conn->error_info, auth_resp_packet->error_no, UNKNOWN_SQLSTATE, auth_resp_packet->error);
+                       SET_CLIENT_ERROR(conn->error_info, auth_resp_packet.error_no, UNKNOWN_SQLSTATE, auth_resp_packet.error);
                }
                goto end;
        }
 
-       SET_NEW_MESSAGE(conn->last_message.s, conn->last_message.l, auth_resp_packet->message, auth_resp_packet->message_len);
+       SET_NEW_MESSAGE(conn->last_message.s, conn->last_message.l, auth_resp_packet.message, auth_resp_packet.message_len);
        ret = PASS;
 end:
-       PACKET_FREE(change_auth_resp_packet);
-       PACKET_FREE(auth_packet);
-       PACKET_FREE(auth_resp_packet);
+       PACKET_FREE(&auth_resp_packet);
        DBG_RETURN(ret);
 }
 /* }}} */
@@ -372,79 +369,73 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
 {
        enum_func_status ret = FAIL;
        const MYSQLND_CHARSET * old_cs = conn->charset;
-       MYSQLND_PACKET_CHANGE_AUTH_RESPONSE * change_auth_resp_packet = NULL;
-       MYSQLND_PACKET_CHG_USER_RESPONSE * chg_user_resp = NULL;
-       MYSQLND_PACKET_AUTH * auth_packet = NULL;
+       MYSQLND_PACKET_CHG_USER_RESPONSE chg_user_resp;
 
        DBG_ENTER("mysqlnd_auth_change_user");
 
-       chg_user_resp = conn->payload_decoder_factory->m.get_change_user_response_packet(conn->payload_decoder_factory, FALSE);
-
-       if (!chg_user_resp) {
-               SET_OOM_ERROR(conn->error_info);
-               goto end;
-       }
+       conn->payload_decoder_factory->m.init_change_user_response_packet(&chg_user_resp);
 
        if (use_full_blown_auth_packet != TRUE) {
-               change_auth_resp_packet = conn->payload_decoder_factory->m.get_change_auth_response_packet(conn->payload_decoder_factory, FALSE);
-               if (!change_auth_resp_packet) {
-                       SET_OOM_ERROR(conn->error_info);
-                       goto end;
-               }
+               MYSQLND_PACKET_CHANGE_AUTH_RESPONSE change_auth_resp_packet;
 
-               change_auth_resp_packet->auth_data = auth_plugin_data;
-               change_auth_resp_packet->auth_data_len = auth_plugin_data_len;
+               conn->payload_decoder_factory->m.init_change_auth_response_packet(&change_auth_resp_packet);
 
-               if (!PACKET_WRITE(change_auth_resp_packet)) {
+               change_auth_resp_packet.auth_data = auth_plugin_data;
+               change_auth_resp_packet.auth_data_len = auth_plugin_data_len;
+
+               if (!PACKET_WRITE(conn, &change_auth_resp_packet)) {
                        SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
                        SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
+                       PACKET_FREE(&change_auth_resp_packet);
                        goto end;
                }
+
+               PACKET_FREE(&change_auth_resp_packet);
        } else {
-               auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE);
+               MYSQLND_PACKET_AUTH auth_packet;
 
-               if (!auth_packet) {
-                       SET_OOM_ERROR(conn->error_info);
-                       goto end;
-               }
+               conn->payload_decoder_factory->m.init_auth_packet(&auth_packet);
 
-               auth_packet->is_change_user_packet = TRUE;
-               auth_packet->user               = user;
-               auth_packet->db                 = db;
-               auth_packet->db_len             = db_len;
-               auth_packet->silent             = silent;
+               auth_packet.is_change_user_packet = TRUE;
+               auth_packet.user                = user;
+               auth_packet.db                  = db;
+               auth_packet.db_len              = db_len;
+               auth_packet.silent              = silent;
 
-               auth_packet->auth_data = auth_plugin_data;
-               auth_packet->auth_data_len = auth_plugin_data_len;
-               auth_packet->auth_plugin_name = auth_protocol;
+               auth_packet.auth_data = auth_plugin_data;
+               auth_packet.auth_data_len = auth_plugin_data_len;
+               auth_packet.auth_plugin_name = auth_protocol;
 
 
                if (conn->m->get_server_version(conn) >= 50123) {
-                       auth_packet->charset_no = conn->charset->nr;
+                       auth_packet.charset_no  = conn->charset->nr;
                }
 
-               if (!PACKET_WRITE(auth_packet)) {
+               if (!PACKET_WRITE(conn, &auth_packet)) {
                        SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
                        SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
+                       PACKET_FREE(&auth_packet);
                        goto end;
                }
+
+               PACKET_FREE(&auth_packet);
        }
 
-       ret = PACKET_READ(chg_user_resp);
-       COPY_CLIENT_ERROR(conn->error_info, chg_user_resp->error_info);
+       ret = PACKET_READ(conn, &chg_user_resp);
+       COPY_CLIENT_ERROR(conn->error_info, chg_user_resp.error_info);
 
-       if (0xFE == chg_user_resp->response_code) {
+       if (0xFE == chg_user_resp.response_code) {
                ret = FAIL;
-               if (!chg_user_resp->new_auth_protocol) {
+               if (!chg_user_resp.new_auth_protocol) {
                        DBG_ERR(mysqlnd_old_passwd);
                        SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
                } else {
-                       *switch_to_auth_protocol = mnd_pestrndup(chg_user_resp->new_auth_protocol, chg_user_resp->new_auth_protocol_len, FALSE);
-                       *switch_to_auth_protocol_len = chg_user_resp->new_auth_protocol_len;
-                       if (chg_user_resp->new_auth_protocol_data) {
-                               *switch_to_auth_protocol_data_len = chg_user_resp->new_auth_protocol_data_len;
+                       *switch_to_auth_protocol = mnd_pestrndup(chg_user_resp.new_auth_protocol, chg_user_resp.new_auth_protocol_len, FALSE);
+                       *switch_to_auth_protocol_len = chg_user_resp.new_auth_protocol_len;
+                       if (chg_user_resp.new_auth_protocol_data) {
+                               *switch_to_auth_protocol_data_len = chg_user_resp.new_auth_protocol_data_len;
                                *switch_to_auth_protocol_data = mnd_emalloc(*switch_to_auth_protocol_data_len);
-                               memcpy(*switch_to_auth_protocol_data, chg_user_resp->new_auth_protocol_data, *switch_to_auth_protocol_data_len);
+                               memcpy(*switch_to_auth_protocol_data, chg_user_resp.new_auth_protocol_data, *switch_to_auth_protocol_data_len);
                        } else {
                                *switch_to_auth_protocol_data = NULL;
                                *switch_to_auth_protocol_data_len = 0;
@@ -460,14 +451,12 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
                  When it gets fixed, there should be one more check here
                */
                if (conn->m->get_server_version(conn) > 50113L &&conn->m->get_server_version(conn) < 50118L) {
-                       MYSQLND_PACKET_OK * redundant_error_packet = conn->payload_decoder_factory->m.get_ok_packet(conn->payload_decoder_factory, FALSE);
-                       if (redundant_error_packet) {
-                               PACKET_READ(redundant_error_packet);
-                               PACKET_FREE(redundant_error_packet);
-                               DBG_INF_FMT("Server is %u, buggy, sends two ERR messages", conn->m->get_server_version(conn));
-                       } else {
-                               SET_OOM_ERROR(conn->error_info);
-                       }
+                       MYSQLND_PACKET_OK redundant_error_packet;
+
+                       conn->payload_decoder_factory->m.init_ok_packet(&redundant_error_packet);
+                       PACKET_READ(conn, &redundant_error_packet);
+                       PACKET_FREE(&redundant_error_packet);
+                       DBG_INF_FMT("Server is %u, buggy, sends two ERR messages", conn->m->get_server_version(conn));
                }
        }
        if (ret == PASS) {
@@ -494,15 +483,13 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
                if (conn->m->get_server_version(conn) < 50123) {
                        ret = conn->m->set_charset(conn, old_cs->name);
                }
-       } else if (ret == FAIL && chg_user_resp->server_asked_323_auth == TRUE) {
+       } else if (ret == FAIL && chg_user_resp.server_asked_323_auth == TRUE) {
                /* old authentication with new server  !*/
                DBG_ERR(mysqlnd_old_passwd);
                SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
        }
 end:
-       PACKET_FREE(change_auth_resp_packet);
-       PACKET_FREE(auth_packet);
-       PACKET_FREE(chg_user_resp);
+       PACKET_FREE(&chg_user_resp);
        DBG_RETURN(ret);
 }
 /* }}} */
@@ -694,45 +681,36 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
                                 pfc_data->sha256_server_public_key? pfc_data->sha256_server_public_key:"n/a",
                                 MYSQLND_G(sha256_server_public_key)? MYSQLND_G(sha256_server_public_key):"n/a");
        if (!fname || fname[0] == '\0') {
-               MYSQLND_PACKET_SHA256_PK_REQUEST * pk_req_packet = NULL;
-               MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * pk_resp_packet = NULL;
+               MYSQLND_PACKET_SHA256_PK_REQUEST pk_req_packet;
+               MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE pk_resp_packet;
 
                do {
                        DBG_INF("requesting the public key from the server");
-                       pk_req_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_packet(conn->payload_decoder_factory, FALSE);
-                       if (!pk_req_packet) {
-                               SET_OOM_ERROR(conn->error_info);
-                               break;
-                       }
-                       pk_resp_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_response_packet(conn->payload_decoder_factory, FALSE);
-                       if (!pk_resp_packet) {
-                               SET_OOM_ERROR(conn->error_info);
-                               PACKET_FREE(pk_req_packet);
-                               break;
-                       }
+                       conn->payload_decoder_factory->m.init_sha256_pk_request_packet(&pk_req_packet);
+                       conn->payload_decoder_factory->m.init_sha256_pk_request_response_packet(&pk_resp_packet);
 
-                       if (! PACKET_WRITE(pk_req_packet)) {
+                       if (! PACKET_WRITE(conn, &pk_req_packet)) {
                                DBG_ERR_FMT("Error while sending public key request packet");
                                php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid());
                                SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
                                break;
                        }
-                       if (FAIL == PACKET_READ(pk_resp_packet) || NULL == pk_resp_packet->public_key) {
+                       if (FAIL == PACKET_READ(conn, &pk_resp_packet) || NULL == pk_resp_packet.public_key) {
                                DBG_ERR_FMT("Error while receiving public key");
                                php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid());
                                SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
                                break;
                        }
-                       DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet->public_key_len, pk_resp_packet->public_key);
+                       DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet.public_key_len, pk_resp_packet.public_key);
                        /* now extract the public key */
                        {
-                               BIO * bio = BIO_new_mem_buf(pk_resp_packet->public_key, pk_resp_packet->public_key_len);
+                               BIO * bio = BIO_new_mem_buf(pk_resp_packet.public_key, pk_resp_packet.public_key_len);
                                ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
                                BIO_free(bio);
                        }
                } while (0);
-               PACKET_FREE(pk_req_packet);
-               PACKET_FREE(pk_resp_packet);
+               PACKET_FREE(&pk_req_packet);
+               PACKET_FREE(&pk_resp_packet);
 
                DBG_INF_FMT("ret=%p", ret);
                DBG_RETURN(ret);
index 3f3635bf930c35e8733b47ae4aa0ed6c30c7cd56..579ae25aefd2cafd1e7121971e99f5b3acbd29de 100644 (file)
@@ -326,17 +326,15 @@ mysqlnd_com_statistics_run(void *cmd)
                                           conn);
 
        if (PASS == ret) {
-               MYSQLND_PACKET_STATS * stats_header = conn->payload_decoder_factory->m.get_stats_packet(conn->payload_decoder_factory, FALSE);
-               if (!stats_header) {
-                       SET_OOM_ERROR(conn->error_info);
-               } else {
-                       if (PASS == (ret = PACKET_READ(stats_header))) {
-                               /* will be freed by Zend, thus don't use the mnd_ allocator */
-                               *message = zend_string_init(stats_header->message.s, stats_header->message.l, 0);
-                               DBG_INF(ZSTR_VAL(*message));
-                       }
-                       PACKET_FREE(stats_header);
+               MYSQLND_PACKET_STATS stats_header;
+
+               conn->payload_decoder_factory->m.init_stats_packet(&stats_header);
+               if (PASS == (ret = PACKET_READ(conn, &stats_header))) {
+                       /* will be freed by Zend, thus don't use the mnd_ allocator */
+                       *message = zend_string_init(stats_header.message.s, stats_header.message.l, 0);
+                       DBG_INF(ZSTR_VAL(*message));
                }
+               PACKET_FREE(&stats_header);
        }
 
        DBG_RETURN(ret);
@@ -1154,7 +1152,7 @@ mysqlnd_com_enable_ssl_run(void *cmd)
        struct st_mysqlnd_protocol_com_enable_ssl_command * command = (struct st_mysqlnd_protocol_com_enable_ssl_command *) cmd;
        enum_func_status ret = FAIL;
        MYSQLND_CONN_DATA * conn = command->context.conn;
-       MYSQLND_PACKET_AUTH auth_packet;
+       MYSQLND_PACKET_AUTH auth_packet;
        size_t client_capabilities = command->context.client_capabilities;
        size_t server_capabilities = command->context.server_capabilities;
 
@@ -1185,15 +1183,11 @@ mysqlnd_com_enable_ssl_run(void *cmd)
        DBG_INF_FMT("CLIENT_SSL_VERIFY_SERVER_CERT=     %d", client_capabilities & CLIENT_SSL_VERIFY_SERVER_CERT? 1:0);
        DBG_INF_FMT("CLIENT_REMEMBER_OPTIONS=           %d", client_capabilities & CLIENT_REMEMBER_OPTIONS? 1:0);
 
-       auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE);
-       if (!auth_packet) {
-               SET_OOM_ERROR(conn->error_info);
-               goto end;
-       }
-       auth_packet->client_flags = client_capabilities;
-       auth_packet->max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
+       conn->payload_decoder_factory->m.init_auth_packet(&auth_packet);
+       auth_packet.client_flags = client_capabilities;
+       auth_packet.max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
 
-       auth_packet->charset_no = command->context.charset_no;
+       auth_packet.charset_no  = command->context.charset_no;
 
 #ifdef MYSQLND_SSL_SUPPORTED
        if (client_capabilities & CLIENT_SSL) {
@@ -1207,7 +1201,7 @@ mysqlnd_com_enable_ssl_run(void *cmd)
                                                                                                        MYSQLND_SSL_PEER_DONT_VERIFY:
                                                                                                        MYSQLND_SSL_PEER_DEFAULT);
                        DBG_INF("Switching to SSL");
-                       if (!PACKET_WRITE(auth_packet)) {
+                       if (!PACKET_WRITE(conn, &auth_packet)) {
                                goto close_conn;
                        }
 
@@ -1219,21 +1213,21 @@ mysqlnd_com_enable_ssl_run(void *cmd)
                }
        }
 #else
-       auth_packet->client_flags &= ~CLIENT_SSL;
-       if (!PACKET_WRITE(auth_packet)) {
+       auth_packet.client_flags &= ~CLIENT_SSL;
+       if (!PACKET_WRITE(conn, &auth_packet)) {
                goto close_conn;
        }
 #endif
        ret = PASS;
 end:
-       PACKET_FREE(auth_packet);
+       PACKET_FREE(&auth_packet);
        DBG_RETURN(ret);
 
 close_conn:
        SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT);
        conn->m->send_close(conn);
        SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
-       PACKET_FREE(auth_packet);
+       PACKET_FREE(&auth_packet);
        DBG_RETURN(ret);
 }
 /* }}} */
@@ -1291,66 +1285,62 @@ mysqlnd_com_handshake_run(void *cmd)
        size_t mysql_flags =  command->context.client_flags;
 
        MYSQLND_CONN_DATA * conn = command->context.conn;
-       MYSQLND_PACKET_GREET greet_packet;
+       MYSQLND_PACKET_GREET greet_packet;
 
        DBG_ENTER("mysqlnd_conn_data::connect_handshake");
        DBG_INF_FMT("stream=%p", conn->vio->data->m.get_stream(conn->vio));
        DBG_INF_FMT("[user=%s] [db=%s:%d] [flags=%llu]", user, db, db_len, mysql_flags);
 
-       greet_packet = conn->payload_decoder_factory->m.get_greet_packet(conn->payload_decoder_factory, FALSE);
-       if (!greet_packet) {
-               SET_OOM_ERROR(conn->error_info);
-               DBG_RETURN(FAIL); /* OOM */
-       }
+       conn->payload_decoder_factory->m.init_greet_packet(&greet_packet);
 
-       if (FAIL == PACKET_READ(greet_packet)) {
+       if (FAIL == PACKET_READ(conn, &greet_packet)) {
                DBG_ERR("Error while reading greeting packet");
                php_error_docref(NULL, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
                goto err;
-       } else if (greet_packet->error_no) {
-               DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
-               SET_CLIENT_ERROR(conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
+       } else if (greet_packet.error_no) {
+               DBG_ERR_FMT("errorno=%u error=%s", greet_packet.error_no, greet_packet.error);
+               SET_CLIENT_ERROR(conn->error_info, greet_packet.error_no, greet_packet.sqlstate, greet_packet.error);
                goto err;
-       } else if (greet_packet->pre41) {
-               DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
+       } else if (greet_packet.pre41) {
+               DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet.server_version);
                php_error_docref(NULL, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
-                                               " is not supported. Server is %-.32s", greet_packet->server_version);
+                                               " is not supported. Server is %-.32s", greet_packet.server_version);
                SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
                                                 "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
                goto err;
        }
 
-       conn->thread_id                 = greet_packet->thread_id;
-       conn->protocol_version  = greet_packet->protocol_version;
-       conn->server_version    = mnd_pestrdup(greet_packet->server_version, conn->persistent);
+       conn->thread_id                 = greet_packet.thread_id;
+       conn->protocol_version  = greet_packet.protocol_version;
+       conn->server_version    = mnd_pestrdup(greet_packet.server_version, conn->persistent);
 
-       conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
+       conn->greet_charset = mysqlnd_find_charset_nr(greet_packet.charset_no);
        if (!conn->greet_charset) {
                php_error_docref(NULL, E_WARNING,
-                       "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet->charset_no);
+                       "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet.charset_no);
                SET_CLIENT_ERROR(conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
                        "Server sent charset unknown to the client. Please, report to the developers");
                goto err;
        }
 
-       conn->server_capabilities       = greet_packet->server_capabilities;
+       conn->server_capabilities       = greet_packet.server_capabilities;
 
        if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
-                                                                                                  greet_packet->authentication_plugin_data, greet_packet->auth_protocol,
-                                                                                                  greet_packet->charset_no, greet_packet->server_capabilities,
+                                                                                                  greet_packet.authentication_plugin_data, greet_packet.auth_protocol,
+                                                                                                  greet_packet.charset_no, greet_packet.server_capabilities,
                                                                                                   conn->options, mysql_flags))
        {
                goto err;
        }
 
        UPSERT_STATUS_RESET(conn->upsert_status);
-       UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, greet_packet->server_status);
+       UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, greet_packet.server_status);
 
-       PACKET_FREE(greet_packet);
+       PACKET_FREE(&greet_packet);
        DBG_RETURN(PASS);
 err:
        conn->server_capabilities = 0;
-       PACKET_FREE(greet_packet);
+       PACKET_FREE(&greet_packet);
        DBG_RETURN(FAIL);
 }
 /* }}} */
index 77e5840fe38aaf7cd53231fce670ae790e54bba5..9af36ac5b6bf2519c02094a2c8459e6d41943114 100644 (file)
@@ -250,7 +250,7 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s)
        /* Follows parameter metadata, we have just to skip it, as libmysql does */
        unsigned int i = 0;
        enum_func_status ret = FAIL;
-       MYSQLND_PACKET_RES_FIELD field_packet;
+       MYSQLND_PACKET_RES_FIELD field_packet;
 
        DBG_ENTER("mysqlnd_stmt_skip_metadata");
        if (!stmt || !conn) {
@@ -258,21 +258,16 @@ mysqlnd_stmt_skip_metadata(MYSQLND_STMT * s)
        }
        DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
 
-       field_packet = conn->payload_decoder_factory->m.get_result_field_packet(conn->payload_decoder_factory, FALSE);
-       if (!field_packet) {
-               SET_OOM_ERROR(stmt->error_info);
-               SET_OOM_ERROR(conn->error_info);
-       } else {
-               ret = PASS;
-               field_packet->skip_parsing = TRUE;
-               for (;i < stmt->param_count; i++) {
-                       if (FAIL == PACKET_READ(field_packet)) {
-                               ret = FAIL;
-                               break;
-                       }
+       conn->payload_decoder_factory->m.init_result_field_packet(&field_packet);
+       ret = PASS;
+       field_packet.skip_parsing = TRUE;
+       for (;i < stmt->param_count; i++) {
+               if (FAIL == PACKET_READ(conn, &field_packet)) {
+                       ret = FAIL;
+                       break;
                }
-               PACKET_FREE(field_packet);
        }
+       PACKET_FREE(&field_packet);
 
        DBG_RETURN(ret);
 }
@@ -285,7 +280,7 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s)
 {
        MYSQLND_STMT_DATA * stmt = s? s->data : NULL;
        MYSQLND_CONN_DATA * conn = stmt? stmt->conn : NULL;
-       MYSQLND_PACKET_PREPARE_RESPONSE prepare_resp;
+       MYSQLND_PACKET_PREPARE_RESPONSE prepare_resp;
        enum_func_status ret = FAIL;
 
        DBG_ENTER("mysqlnd_stmt_read_prepare_response");
@@ -294,30 +289,25 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s)
        }
        DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
 
-       prepare_resp = conn->payload_decoder_factory->m.get_prepare_response_packet(conn->payload_decoder_factory, FALSE);
-       if (!prepare_resp) {
-               SET_OOM_ERROR(stmt->error_info);
-               SET_OOM_ERROR(conn->error_info);
-               goto done;
-       }
+       conn->payload_decoder_factory->m.init_prepare_response_packet(&prepare_resp);
 
-       if (FAIL == PACKET_READ(prepare_resp)) {
+       if (FAIL == PACKET_READ(conn, &prepare_resp)) {
                goto done;
        }
 
-       if (0xFF == prepare_resp->error_code) {
-               COPY_CLIENT_ERROR(stmt->error_info, prepare_resp->error_info);
-               COPY_CLIENT_ERROR(conn->error_info, prepare_resp->error_info);
+       if (0xFF == prepare_resp.error_code) {
+               COPY_CLIENT_ERROR(stmt->error_info, prepare_resp.error_info);
+               COPY_CLIENT_ERROR(conn->error_info, prepare_resp.error_info);
                goto done;
        }
        ret = PASS;
-       stmt->stmt_id = prepare_resp->stmt_id;
-       UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, prepare_resp->warning_count);
+       stmt->stmt_id = prepare_resp.stmt_id;
+       UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, prepare_resp.warning_count);
        UPSERT_STATUS_SET_AFFECTED_ROWS(stmt->upsert_status, 0);  /* be like libmysql */
-       stmt->field_count = conn->field_count = prepare_resp->field_count;
-       stmt->param_count = prepare_resp->param_count;
+       stmt->field_count = conn->field_count = prepare_resp.field_count;
+       stmt->param_count = prepare_resp.param_count;
 done:
-       PACKET_FREE(prepare_resp);
+       PACKET_FREE(&prepare_resp);
 
        DBG_RETURN(ret);
 }
@@ -330,7 +320,7 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s)
 {
        MYSQLND_STMT_DATA * stmt = s? s->data : NULL;
        MYSQLND_CONN_DATA * conn = stmt? stmt->conn : NULL;
-       MYSQLND_PACKET_EOF fields_eof;
+       MYSQLND_PACKET_EOF fields_eof;
        enum_func_status ret = FAIL;
 
        DBG_ENTER("mysqlnd_stmt_prepare_read_eof");
@@ -339,29 +329,23 @@ mysqlnd_stmt_prepare_read_eof(MYSQLND_STMT * s)
        }
        DBG_INF_FMT("stmt=%lu", stmt->stmt_id);
 
-       fields_eof = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE);
-       if (!fields_eof) {
-               SET_OOM_ERROR(stmt->error_info);
-               SET_OOM_ERROR(conn->error_info);
-       } else {
-               if (FAIL == (ret = PACKET_READ(fields_eof))) {
-                       if (stmt->result) {
-                               stmt->result->m.free_result_contents(stmt->result);
-                               mnd_efree(stmt->result);
-                               /* XXX: This will crash, because we will null also the methods.
-                                       But seems it happens in extreme cases or doesn't. Should be fixed by exporting a function
-                                       (from mysqlnd_driver.c?) to do the reset.
-                                       This bad handling is also in mysqlnd_result.c
-                               */
-                               memset(stmt, 0, sizeof(MYSQLND_STMT_DATA));
-                               stmt->state = MYSQLND_STMT_INITTED;
-                       }
-               } else {
-                       UPSERT_STATUS_SET_SERVER_STATUS(stmt->upsert_status, fields_eof->server_status);
-                       UPSERT_STATUS_SET_WARNINGS(stmt->upsert_status, fields_eof->warning_count);
-                       stmt->state = MYSQLND_STMT_PREPARED;
+       conn->payload_decoder_factory->m.init_eof_packet(&fields_eof);
+       if (FAIL == (ret = PACKET_READ(conn, &fields_eof))) {
+               if (stmt->result) {
+                       stmt->result->m.free_result_contents(stmt->result);
+                       mnd_efree(stmt->result);
+                       /* XXX: This will crash, because we will null also the methods.
+                               But seems it happens in extreme cases or doesn't. Should be fixed by exporting a function
+                               (from mysqlnd_driver.c?) to do the reset.
+                               This bad handling is also in mysqlnd_result.c
+                       */
+                       memset(stmt, 0, sizeof(MYSQLND_STMT_DATA));
+                       stmt->state = MYSQLND_STMT_INITTED;
                }
-               PACKET_FREE(fields_eof);
+       } else {
+               UPSERT_STATUS_SET_SERVER_STATUS(stmt->upsert_status, fields_eof.server_status);
+               UPSERT_STATUS_SET_WARNINGS(stmt->upsert_status, fields_eof.warning_count);
+               stmt->state = MYSQLND_STMT_PREPARED;
        }
 
        DBG_RETURN(ret);
@@ -892,7 +876,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi
          If we skip rows (stmt == NULL || stmt->result_bind == NULL) we have to
          result->unbuf->m.free_last_data() before it. The function returns always true.
        */
-       if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
+       if (PASS == (ret = PACKET_READ(conn, row_packet)) && !row_packet->eof) {
                unsigned int i, field_count = result->field_count;
 
                if (!row_packet->skip_extraction) {
@@ -1081,7 +1065,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, const unsigned
        row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE;
 
        UPSERT_STATUS_RESET(stmt->upsert_status);
-       if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
+       if (PASS == (ret = PACKET_READ(conn, row_packet)) && !row_packet->eof) {
                const MYSQLND_RES_METADATA * const meta = result->meta;
                unsigned int i, field_count = result->field_count;
 
@@ -1147,7 +1131,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES * result, void * param, const unsigned
                        row_packet->row_buffer = NULL;
                }
                /* We asked for one row, the next one should be EOF, eat it */
-               ret = PACKET_READ(row_packet);
+               ret = PACKET_READ(conn, row_packet);
                if (row_packet->row_buffer) {
                        row_packet->result_set_memory_pool->free_chunk(
                                row_packet->result_set_memory_pool, row_packet->row_buffer);
index 13c7b65271e0f8be5c186caa6b2bad9aa0a21cb2..1035d0379fc633bc38be94c6c4ba2f41c237d458 100644 (file)
@@ -191,6 +191,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, free_result)(MYSQLND_RES_UNBUFFERED *
        /* must be free before because references the memory pool */
        if (result->row_packet) {
                PACKET_FREE(result->row_packet);
+               mnd_efree(result->row_packet);
                result->row_packet = NULL;
        }
 
@@ -407,29 +408,23 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
 {
        enum_func_status ret;
        MYSQLND_STMT_DATA * stmt = s ? s->data : NULL;
-       MYSQLND_PACKET_RSET_HEADER * rset_header = NULL;
-       MYSQLND_PACKET_EOF * fields_eof = NULL;
+       MYSQLND_PACKET_RSET_HEADER rset_header;
+       MYSQLND_PACKET_EOF fields_eof;
 
        DBG_ENTER("mysqlnd_query_read_result_set_header");
        DBG_INF_FMT("stmt=%lu", stmt? stmt->stmt_id:0);
 
        ret = FAIL;
        do {
-               rset_header = conn->payload_decoder_factory->m.get_rset_header_packet(conn->payload_decoder_factory, FALSE);
-               if (!rset_header) {
-                       SET_OOM_ERROR(conn->error_info);
-                       ret = FAIL;
-                       break;
-               }
-
+               conn->payload_decoder_factory->m.init_rset_header_packet(&rset_header);
                UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
 
-               if (FAIL == (ret = PACKET_READ(rset_header))) {
+               if (FAIL == (ret = PACKET_READ(conn, &rset_header))) {
                        php_error_docref(NULL, E_WARNING, "Error reading result set's header");
                        break;
                }
 
-               if (rset_header->error_info.error_no) {
+               if (rset_header.error_info.error_no) {
                        /*
                          Cover a protocol design error: error packet does not
                          contain the server status. Therefore, the client has no way
@@ -444,23 +439,23 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                          This will copy the error code and the messages, as they
                          are buffers in the struct
                        */
-                       COPY_CLIENT_ERROR(conn->error_info, rset_header->error_info);
+                       COPY_CLIENT_ERROR(conn->error_info, rset_header.error_info);
                        ret = FAIL;
-                       DBG_ERR_FMT("error=%s", rset_header->error_info.error);
+                       DBG_ERR_FMT("error=%s", rset_header.error_info.error);
                        /* Return back from CONN_QUERY_SENT */
                        SET_CONNECTION_STATE(&conn->state, CONN_READY);
                        break;
                }
                conn->error_info->error_no = 0;
 
-               switch (rset_header->field_count) {
+               switch (rset_header.field_count) {
                        case MYSQLND_NULL_LENGTH: {     /* LOAD DATA LOCAL INFILE */
                                zend_bool is_warning;
                                DBG_INF("LOAD DATA");
                                conn->last_query_type = QUERY_LOAD_LOCAL;
                                conn->field_count = 0; /* overwrite previous value, or the last value could be used and lead to bug#53503 */
                                SET_CONNECTION_STATE(&conn->state, CONN_SENDING_LOAD_DATA);
-                               ret = mysqlnd_handle_local_infile(conn, rset_header->info_or_local_file.s, &is_warning);
+                               ret = mysqlnd_handle_local_infile(conn, rset_header.info_or_local_file.s, &is_warning);
                                SET_CONNECTION_STATE(&conn->state,  (ret == PASS || is_warning == TRUE)? CONN_READY:CONN_QUIT_SENT);
                                MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_NON_RSET_QUERY);
                                break;
@@ -468,14 +463,14 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                        case 0:                         /* UPSERT */
                                DBG_INF("UPSERT");
                                conn->last_query_type = QUERY_UPSERT;
-                               conn->field_count = rset_header->field_count;
+                               conn->field_count = rset_header.field_count;
                                UPSERT_STATUS_RESET(conn->upsert_status);
-                               UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, rset_header->warning_count);
-                               UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, rset_header->server_status);
-                               UPSERT_STATUS_SET_AFFECTED_ROWS(conn->upsert_status, rset_header->affected_rows);
-                               UPSERT_STATUS_SET_LAST_INSERT_ID(conn->upsert_status, rset_header->last_insert_id);
+                               UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, rset_header.warning_count);
+                               UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, rset_header.server_status);
+                               UPSERT_STATUS_SET_AFFECTED_ROWS(conn->upsert_status, rset_header.affected_rows);
+                               UPSERT_STATUS_SET_LAST_INSERT_ID(conn->upsert_status, rset_header.last_insert_id);
                                SET_NEW_MESSAGE(conn->last_message.s, conn->last_message.l,
-                                                               rset_header->info_or_local_file.s, rset_header->info_or_local_file.l);
+                                                               rset_header.info_or_local_file.s, rset_header.info_or_local_file.l);
                                /* Result set can follow UPSERT statement, check server_status */
                                if (UPSERT_STATUS_GET_SERVER_STATUS(conn->upsert_status) & SERVER_MORE_RESULTS_EXISTS) {
                                        SET_CONNECTION_STATE(&conn->state, CONN_NEXT_RESULT_PENDING);
@@ -500,9 +495,9 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                                conn->last_query_type = QUERY_SELECT;
                                SET_CONNECTION_STATE(&conn->state, CONN_FETCHING_DATA);
                                /* PS has already allocated it */
-                               conn->field_count = rset_header->field_count;
+                               conn->field_count = rset_header.field_count;
                                if (!stmt) {
-                                       result = conn->current_result = conn->m->result_init(rset_header->field_count);
+                                       result = conn->current_result = conn->m->result_init(rset_header.field_count);
                                } else {
                                        if (!stmt->result) {
                                                DBG_INF("This is 'SHOW'/'EXPLAIN'-like query.");
@@ -511,7 +506,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                                                  prepared statements can't send result set metadata for these queries
                                                  on prepare stage. Read it now.
                                                */
-                                               result = stmt->result = conn->m->result_init(rset_header->field_count);
+                                               result = stmt->result = conn->m->result_init(rset_header.field_count);
                                        } else {
                                                /*
                                                  Update result set metadata if it for some reason changed between
@@ -545,13 +540,8 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                                }
 
                                /* Check for SERVER_STATUS_MORE_RESULTS if needed */
-                               fields_eof = conn->payload_decoder_factory->m.get_eof_packet(conn->payload_decoder_factory, FALSE);
-                               if (!fields_eof) {
-                                       SET_OOM_ERROR(conn->error_info);
-                                       ret = FAIL;
-                                       break;
-                               }
-                               if (FAIL == (ret = PACKET_READ(fields_eof))) {
+                               conn->payload_decoder_factory->m.init_eof_packet(&fields_eof);
+                               if (FAIL == (ret = PACKET_READ(conn, &fields_eof))) {
                                        DBG_ERR("Error occurred while reading the EOF packet");
                                        result->m.free_result_contents(result);
                                        mnd_efree(result);
@@ -568,8 +558,8 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                                                stmt->state = MYSQLND_STMT_INITTED;
                                        }
                                } else {
-                                       DBG_INF_FMT("warnings=%u server_status=%u", fields_eof->warning_count, fields_eof->server_status);
-                                       UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, fields_eof->warning_count);
+                                       DBG_INF_FMT("warnings=%u server_status=%u", fields_eof.warning_count, fields_eof.server_status);
+                                       UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, fields_eof.warning_count);
                                        /*
                                          If SERVER_MORE_RESULTS_EXISTS is set then this is either MULTI_QUERY or a CALL()
                                          The first packet after sending the query/com_execute has the bit set only
@@ -577,22 +567,22 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
                                          will include many result sets. What actually matters are the bits set at the end
                                          of every result set (the EOF packet).
                                        */
-                                       UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, fields_eof->server_status);
-                                       if (fields_eof->server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) {
+                                       UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, fields_eof.server_status);
+                                       if (fields_eof.server_status & SERVER_QUERY_NO_GOOD_INDEX_USED) {
                                                statistic = STAT_BAD_INDEX_USED;
-                                       } else if (fields_eof->server_status & SERVER_QUERY_NO_INDEX_USED) {
+                                       } else if (fields_eof.server_status & SERVER_QUERY_NO_INDEX_USED) {
                                                statistic = STAT_NO_INDEX_USED;
-                                       } else if (fields_eof->server_status & SERVER_QUERY_WAS_SLOW) {
+                                       } else if (fields_eof.server_status & SERVER_QUERY_WAS_SLOW) {
                                                statistic = STAT_QUERY_WAS_SLOW;
                                        }
                                        MYSQLND_INC_CONN_STATISTIC(conn->stats, statistic);
                                }
                        } while (0);
-                       PACKET_FREE(fields_eof);
+                       PACKET_FREE(&fields_eof);
                        break; /* switch break */
                }
        } while (0);
-       PACKET_FREE(rset_header);
+       PACKET_FREE(&rset_header);
 
        DBG_INF(ret == PASS? "PASS":"FAIL");
        DBG_RETURN(ret);
@@ -714,7 +704,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
          If we skip rows (row == NULL) we have to
          result->m.unbuffered_free_last_data() before it. The function returns always true.
        */
-       if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
+       if (PASS == (ret = PACKET_READ(conn, row_packet)) && !row_packet->eof) {
                result->unbuf->m.free_last_data(result->unbuf, conn->stats);
 
                result->unbuf->last_row_data = row_packet->fields;
@@ -835,7 +825,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void
          If we skip rows (row == NULL) we have to
          result->m.unbuffered_free_last_data() before it. The function returns always true.
        */
-       if (PASS == (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
+       if (PASS == (ret = PACKET_READ(conn, row_packet)) && !row_packet->eof) {
                result->unbuf->m.free_last_data(result->unbuf, conn->stats);
 
                result->unbuf->last_row_data = row_packet->fields;
@@ -958,10 +948,9 @@ MYSQLND_METHOD(mysqlnd_res, use_result)(MYSQLND_RES * const result, const zend_b
        */
        /* FALSE = non-persistent */
        {
-               struct st_mysqlnd_packet_row * row_packet = conn->payload_decoder_factory->m.get_row_packet(conn->payload_decoder_factory, FALSE);
-               if (!row_packet) {
-                       goto oom;
-               }
+               struct st_mysqlnd_packet_row *row_packet = mnd_emalloc(sizeof(struct st_mysqlnd_packet_row));
+
+               conn->payload_decoder_factory->m.init_row_packet(row_packet);
                row_packet->result_set_memory_pool = result->unbuf->result_set_memory_pool;
                row_packet->field_count = result->field_count;
                row_packet->binary_protocol = ps;
@@ -1290,7 +1279,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
        enum_func_status ret;
        unsigned int next_extend = STORE_RESULT_PREALLOCATED_SET_IF_NOT_EMPTY, free_rows = 1;
        MYSQLND_RES_BUFFERED * set = result->stored_data;
-       MYSQLND_PACKET_ROW * row_packet = NULL;
+       MYSQLND_PACKET_ROW row_packet;
 
        DBG_ENTER("mysqlnd_res::store_result_fetch_data");
        if (!set || !row_buffers) {
@@ -1305,23 +1294,18 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
                        goto end;
                }
        }
-       /* non-persistent */
-       row_packet = conn->payload_decoder_factory->m.get_row_packet(conn->payload_decoder_factory, FALSE);
-       if (!row_packet) {
-               SET_OOM_ERROR(conn->error_info);
-               ret = FAIL;
-               goto end;
-       }
+
+       conn->payload_decoder_factory->m.init_row_packet(&row_packet);
        set->references = 1;
 
-       row_packet->result_set_memory_pool = result->stored_data->result_set_memory_pool;
-       row_packet->field_count = meta->field_count;
-       row_packet->binary_protocol = binary_protocol;
-       row_packet->fields_metadata = meta->fields;
+       row_packet.result_set_memory_pool = result->stored_data->result_set_memory_pool;
+       row_packet.field_count = meta->field_count;
+       row_packet.binary_protocol = binary_protocol;
+       row_packet.fields_metadata = meta->fields;
 
-       row_packet->skip_extraction = TRUE; /* let php_mysqlnd_rowp_read() not allocate row_packet->fields, we will do it */
+       row_packet.skip_extraction = TRUE; /* let php_mysqlnd_rowp_read() not allocate row_packet.fields, we will do it */
 
-       while (FAIL != (ret = PACKET_READ(row_packet)) && !row_packet->eof) {
+       while (FAIL != (ret = PACKET_READ(conn, &row_packet)) && !row_packet.eof) {
                if (!free_rows) {
                        uint64_t total_allocated_rows = free_rows = next_extend = next_extend * 11 / 10; /* extend with 10% */
                        MYSQLND_MEMORY_POOL_CHUNK ** new_row_buffers;
@@ -1331,24 +1315,24 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
                        if (total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *) > SIZE_MAX) {
                                SET_OOM_ERROR(conn->error_info);
                                ret = FAIL;
-                               goto end;
+                               goto free_end;
                        }
                        new_row_buffers = mnd_perealloc(*row_buffers, (size_t)(total_allocated_rows * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
                        if (!new_row_buffers) {
                                SET_OOM_ERROR(conn->error_info);
                                ret = FAIL;
-                               goto end;
+                               goto free_end;
                        }
                        *row_buffers = new_row_buffers;
                }
                free_rows--;
-               (*row_buffers)[set->row_count] = row_packet->row_buffer;
+               (*row_buffers)[set->row_count] = row_packet.row_buffer;
 
                set->row_count++;
 
                /* So row_packet's destructor function won't efree() it */
-               row_packet->fields = NULL;
-               row_packet->row_buffer = NULL;
+               row_packet.fields = NULL;
+               row_packet.row_buffer = NULL;
 
                /*
                  No need to FREE_ALLOCA as we can reuse the
@@ -1364,10 +1348,10 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
                                                                           set->row_count);
 
        /* Finally clean */
-       if (row_packet->eof) {
+       if (row_packet.eof) {
                UPSERT_STATUS_RESET(conn->upsert_status);
-               UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, row_packet->warning_count);
-               UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, row_packet->server_status);
+               UPSERT_STATUS_SET_WARNINGS(conn->upsert_status, row_packet.warning_count);
+               UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, row_packet.server_status);
        }
        /* save some memory */
        if (free_rows) {
@@ -1375,7 +1359,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
                if (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *) > SIZE_MAX) {
                        SET_OOM_ERROR(conn->error_info);
                        ret = FAIL;
-                       goto end;
+                       goto free_end;
                }
                *row_buffers = mnd_perealloc(*row_buffers, (size_t) (set->row_count * sizeof(MYSQLND_MEMORY_POOL_CHUNK *)), 0);
        }
@@ -1387,7 +1371,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
        }
 
        if (ret == FAIL) {
-               COPY_CLIENT_ERROR(&set->error_info, row_packet->error_info);
+               COPY_CLIENT_ERROR(&set->error_info, row_packet.error_info);
        } else {
                /* libmysql's documentation says it should be so for SELECT statements */
                UPSERT_STATUS_SET_AFFECTED_ROWS(conn->upsert_status, set->row_count);
@@ -1397,8 +1381,9 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
                                (uint32_t) set->row_count,
                                UPSERT_STATUS_GET_WARNINGS(conn->upsert_status),
                                UPSERT_STATUS_GET_SERVER_STATUS(conn->upsert_status));
+free_end:
+       PACKET_FREE(&row_packet);
 end:
-       PACKET_FREE(row_packet);
        DBG_INF_FMT("rows=%llu", (unsigned long long)result->stored_data->row_count);
        DBG_RETURN(ret);
 }
index bdee5cf8eadf5cca346332c0b7897575e0a928aa..1db22f507d93ecbe01a1f90abf7a2274f064f66e 100644 (file)
@@ -53,15 +53,11 @@ static enum_func_status
 MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn)
 {
        unsigned int i = 0;
-       MYSQLND_PACKET_RES_FIELD field_packet;
+       MYSQLND_PACKET_RES_FIELD field_packet;
 
        DBG_ENTER("mysqlnd_res_meta::read_metadata");
 
-       field_packet = conn->payload_decoder_factory->m.get_result_field_packet(conn->payload_decoder_factory, FALSE);
-       if (!field_packet) {
-               SET_OOM_ERROR(conn->error_info);
-               DBG_RETURN(FAIL);
-       }
+       conn->payload_decoder_factory->m.init_result_field_packet(&field_packet);
        for (;i < meta->field_count; i++) {
                zend_ulong idx;
 
@@ -71,31 +67,31 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
                        meta->fields[i].root = NULL;
                }
 
-               field_packet->metadata = &(meta->fields[i]);
-               if (FAIL == PACKET_READ(field_packet)) {
-                       PACKET_FREE(field_packet);
+               field_packet.metadata = &(meta->fields[i]);
+               if (FAIL == PACKET_READ(conn, &field_packet)) {
+                       PACKET_FREE(&field_packet);
                        DBG_RETURN(FAIL);
                }
-               if (field_packet->error_info.error_no) {
-                       COPY_CLIENT_ERROR(conn->error_info, field_packet->error_info);
+               if (field_packet.error_info.error_no) {
+                       COPY_CLIENT_ERROR(conn->error_info, field_packet.error_info);
                        /* Return back from CONN_QUERY_SENT */
-                       PACKET_FREE(field_packet);
+                       PACKET_FREE(&field_packet);
                        DBG_RETURN(FAIL);
                }
 
                if (mysqlnd_ps_fetch_functions[meta->fields[i].type].func == NULL) {
                        DBG_ERR_FMT("Unknown type %u sent by the server.  Please send a report to the developers", meta->fields[i].type);
                        php_error_docref(NULL, E_WARNING, "Unknown type %u sent by the server. Please send a report to the developers", meta->fields[i].type);
-                       PACKET_FREE(field_packet);
+                       PACKET_FREE(&field_packet);
                        DBG_RETURN(FAIL);
                }
 
                /* For BC we have to check whether the key is numeric and use it like this */
-               if ((meta->zend_hash_keys[i].is_numeric = ZEND_HANDLE_NUMERIC(field_packet->metadata->sname, idx))) {
+               if ((meta->zend_hash_keys[i].is_numeric = ZEND_HANDLE_NUMERIC(field_packet.metadata->sname, idx))) {
                        meta->zend_hash_keys[i].key = idx;
                }
        }
-       PACKET_FREE(field_packet);
+       PACKET_FREE(&field_packet);
 
        DBG_RETURN(PASS);
 }
index a57e91c824a9cef157976d43e50e68475f2be1db..3d76bc22bf6feec650b1f2944bb8707075f95d46 100644 (file)
@@ -955,9 +955,10 @@ struct st_mysqlnd_connection
 
 
 
-struct st_mysqlnd_packet_greet;
 struct st_mysqlnd_packet_greet;
 struct st_mysqlnd_packet_auth;
+struct st_mysqlnd_packet_auth_response;
+struct st_mysqlnd_packet_change_auth_response;
 struct st_mysqlnd_packet_ok;
 struct st_mysqlnd_packet_command;
 struct st_mysqlnd_packet_eof;
@@ -971,21 +972,21 @@ struct st_mysqlnd_packet_auth_pam;
 struct st_mysqlnd_packet_sha256_pk_request;
 struct st_mysqlnd_packet_sha256_pk_request_response;
 
-typedef struct st_mysqlnd_packet_greet *               (*func_mysqlnd_protocol_payload_decoder_factory__get_greet_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_auth *                        (*func_mysqlnd_protocol_payload_decoder_factory__get_auth_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_auth_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_auth_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_change_auth_response *        (*func_mysqlnd_protocol_payload_decoder_factory__get_change_auth_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_ok *                  (*func_mysqlnd_protocol_payload_decoder_factory__get_ok_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_command *             (*func_mysqlnd_protocol_payload_decoder_factory__get_command_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_eof *                 (*func_mysqlnd_protocol_payload_decoder_factory__get_eof_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_rset_header * (*func_mysqlnd_protocol_payload_decoder_factory__get_rset_header_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_res_field *   (*func_mysqlnd_protocol_payload_decoder_factory__get_result_field_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_row *                 (*func_mysqlnd_protocol_payload_decoder_factory__get_row_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_stats *               (*func_mysqlnd_protocol_payload_decoder_factory__get_stats_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_prepare_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_prepare_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_chg_user_resp*(*func_mysqlnd_protocol_payload_decoder_factory__get_change_user_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_sha256_pk_request *(*func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
-typedef struct st_mysqlnd_packet_sha256_pk_request_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_greet_packet)(struct st_mysqlnd_packet_greet *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_auth_packet)(struct st_mysqlnd_packet_auth *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_auth_response_packet)(struct st_mysqlnd_packet_auth_response *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_change_auth_response_packet)(struct st_mysqlnd_packet_change_auth_response *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_ok_packet)(struct st_mysqlnd_packet_ok *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_command_packet)(struct st_mysqlnd_packet_command *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_eof_packet)(struct st_mysqlnd_packet_eof *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_rset_header_packet)(struct st_mysqlnd_packet_rset_header *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_result_field_packet)(struct st_mysqlnd_packet_res_field *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_row_packet)(struct st_mysqlnd_packet_row *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_stats_packet)(struct st_mysqlnd_packet_stats *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_prepare_response_packet)(struct st_mysqlnd_packet_prepare_response *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_change_user_response_packet)(struct st_mysqlnd_packet_chg_user_resp *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_packet)(struct st_mysqlnd_packet_sha256_pk_request *packet);
+typedef void (*func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_response_packet)(struct st_mysqlnd_packet_sha256_pk_request_response *packet);
 
 typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command)(
                        MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory,
@@ -1026,21 +1027,21 @@ typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_c
 
 MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory)
 {
-       func_mysqlnd_protocol_payload_decoder_factory__get_greet_packet get_greet_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_auth_packet get_auth_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_auth_response_packet get_auth_response_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_change_auth_response_packet get_change_auth_response_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_ok_packet get_ok_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_command_packet get_command_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_eof_packet get_eof_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_rset_header_packet get_rset_header_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_result_field_packet get_result_field_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_row_packet get_row_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_stats_packet get_stats_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_prepare_response_packet get_prepare_response_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_change_user_response_packet get_change_user_response_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_packet get_sha256_pk_request_packet;
-       func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_response_packet get_sha256_pk_request_response_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_greet_packet init_greet_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_auth_packet init_auth_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_auth_response_packet init_auth_response_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_change_auth_response_packet init_change_auth_response_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_ok_packet init_ok_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_command_packet init_command_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_eof_packet init_eof_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_rset_header_packet init_rset_header_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_result_field_packet init_result_field_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_row_packet init_row_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_stats_packet init_stats_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_prepare_response_packet init_prepare_response_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_change_user_response_packet init_change_user_response_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_packet init_sha256_pk_request_packet;
+       func_mysqlnd_protocol_payload_decoder_factory__init_sha256_pk_request_response_packet init_sha256_pk_request_response_packet;
 
        func_mysqlnd_protocol_payload_decoder_factory__send_command send_command;
        func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response;
@@ -1217,7 +1218,7 @@ struct st_mysqlnd_unbuffered_result
 
        MYSQLND_MEMORY_POOL     *result_set_memory_pool;
 
-       struct st_mysqlnd_packet_row * row_packet;
+       struct st_mysqlnd_packet_row *row_packet;
 
        unsigned int            field_count;
 
index 9c92ec5e36eac57acf484143fcb63ab1c2590c54..7b0c127117183aebb5877fdd2759e291146366c9 100644 (file)
@@ -322,18 +322,18 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header,
 
 /* {{{ php_mysqlnd_greet_read */
 static enum_func_status
-php_mysqlnd_greet_read(void * _packet)
+php_mysqlnd_greet_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        zend_uchar buf[2048];
        const zend_uchar * p = buf;
        const zend_uchar * const begin = buf;
        const zend_uchar * pad_start = NULL;
        MYSQLND_PACKET_GREET *packet= (MYSQLND_PACKET_GREET *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
 
        DBG_ENTER("php_mysqlnd_greet_read");
 
@@ -465,7 +465,7 @@ premature_end:
 
 /* {{{ php_mysqlnd_greet_free_mem */
 static
-void php_mysqlnd_greet_free_mem(void * _packet, zend_bool stack_allocation)
+void php_mysqlnd_greet_free_mem(void * _packet)
 {
        MYSQLND_PACKET_GREET *p= (MYSQLND_PACKET_GREET *) _packet;
        if (p->server_version) {
@@ -480,9 +480,6 @@ void php_mysqlnd_greet_free_mem(void * _packet, zend_bool stack_allocation)
                efree(p->auth_protocol);
                p->auth_protocol = NULL;
        }
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
 }
 /* }}} */
 
@@ -491,18 +488,17 @@ void php_mysqlnd_greet_free_mem(void * _packet, zend_bool stack_allocation)
 
 /* {{{ php_mysqlnd_auth_write */
 static
-size_t php_mysqlnd_auth_write(void * _packet)
+size_t php_mysqlnd_auth_write(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        zend_uchar buffer[AUTH_WRITE_BUFFER_LEN];
        zend_uchar *p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */
        size_t len;
        MYSQLND_PACKET_AUTH * packet= (MYSQLND_PACKET_AUTH *) _packet;
-       MYSQLND_CONN_DATA * conn = packet->header.conn;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
 
        DBG_ENTER("php_mysqlnd_auth_write");
 
@@ -641,30 +637,18 @@ size_t php_mysqlnd_auth_write(void * _packet)
 /* }}} */
 
 
-/* {{{ php_mysqlnd_auth_free_mem */
-static
-void php_mysqlnd_auth_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       if (!stack_allocation) {
-               MYSQLND_PACKET_AUTH * p = (MYSQLND_PACKET_AUTH *) _packet;
-               mnd_pefree(p, p->header.persistent);
-       }
-}
-/* }}} */
-
-
 #define AUTH_RESP_BUFFER_SIZE 2048
 
 /* {{{ php_mysqlnd_auth_response_read */
 static enum_func_status
-php_mysqlnd_auth_response_read(void * _packet)
+php_mysqlnd_auth_response_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        register MYSQLND_PACKET_AUTH_RESPONSE * packet= (MYSQLND_PACKET_AUTH_RESPONSE *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        zend_uchar local_buf[AUTH_RESP_BUFFER_SIZE];
        size_t buf_len = pfc->cmd_buffer.buffer? pfc->cmd_buffer.length: AUTH_RESP_BUFFER_SIZE;
        zend_uchar *buf = pfc->cmd_buffer.buffer? (zend_uchar *) pfc->cmd_buffer.buffer : local_buf;
@@ -756,7 +740,7 @@ premature_end:
 
 /* {{{ php_mysqlnd_auth_response_free_mem */
 static void
-php_mysqlnd_auth_response_free_mem(void * _packet, zend_bool stack_allocation)
+php_mysqlnd_auth_response_free_mem(void * _packet)
 {
        MYSQLND_PACKET_AUTH_RESPONSE * p = (MYSQLND_PACKET_AUTH_RESPONSE *) _packet;
        if (p->message) {
@@ -774,24 +758,20 @@ php_mysqlnd_auth_response_free_mem(void * _packet, zend_bool stack_allocation)
                p->new_auth_protocol_data = NULL;
        }
        p->new_auth_protocol_data_len = 0;
-
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
 }
 /* }}} */
 
 
 /* {{{ php_mysqlnd_change_auth_response_write */
 static size_t
-php_mysqlnd_change_auth_response_write(void * _packet)
+php_mysqlnd_change_auth_response_write(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *packet= (MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        zend_uchar * buffer = pfc->cmd_buffer.length >= packet->auth_data_len? pfc->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len);
        zend_uchar * p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */
 
@@ -816,30 +796,18 @@ php_mysqlnd_change_auth_response_write(void * _packet)
 /* }}} */
 
 
-/* {{{ php_mysqlnd_change_auth_response_free_mem */
-static void
-php_mysqlnd_change_auth_response_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       if (!stack_allocation) {
-               MYSQLND_PACKET_CHANGE_AUTH_RESPONSE * p = (MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *) _packet;
-               mnd_pefree(p, p->header.persistent);
-       }
-}
-/* }}} */
-
-
 #define OK_BUFFER_SIZE 2048
 
 /* {{{ php_mysqlnd_ok_read */
 static enum_func_status
-php_mysqlnd_ok_read(void * _packet)
+php_mysqlnd_ok_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        register MYSQLND_PACKET_OK *packet= (MYSQLND_PACKET_OK *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        zend_uchar local_buf[OK_BUFFER_SIZE];
        size_t buf_len = pfc->cmd_buffer.buffer? pfc->cmd_buffer.length : OK_BUFFER_SIZE;
        zend_uchar * buf = pfc->cmd_buffer.buffer? (zend_uchar *) pfc->cmd_buffer.buffer : local_buf;
@@ -908,23 +876,20 @@ premature_end:
 
 /* {{{ php_mysqlnd_ok_free_mem */
 static void
-php_mysqlnd_ok_free_mem(void * _packet, zend_bool stack_allocation)
+php_mysqlnd_ok_free_mem(void * _packet)
 {
        MYSQLND_PACKET_OK *p= (MYSQLND_PACKET_OK *) _packet;
        if (p->message) {
                mnd_efree(p->message);
                p->message = NULL;
        }
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
 }
 /* }}} */
 
 
 /* {{{ php_mysqlnd_eof_read */
 static enum_func_status
-php_mysqlnd_eof_read(void * _packet)
+php_mysqlnd_eof_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        /*
          EOF packet is since 4.1 five bytes long,
@@ -933,11 +898,11 @@ php_mysqlnd_eof_read(void * _packet)
          Error : error_code + '#' + sqlstate + MYSQLND_ERRMSG_SIZE
        */
        MYSQLND_PACKET_EOF *packet= (MYSQLND_PACKET_EOF *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        size_t buf_len = pfc->cmd_buffer.length;
        zend_uchar * buf = (zend_uchar *) pfc->cmd_buffer.buffer;
        const zend_uchar * p = buf;
@@ -996,27 +961,16 @@ premature_end:
 /* }}} */
 
 
-/* {{{ php_mysqlnd_eof_free_mem */
-static
-void php_mysqlnd_eof_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       if (!stack_allocation) {
-               mnd_pefree(_packet, ((MYSQLND_PACKET_EOF *)_packet)->header.persistent);
-       }
-}
-/* }}} */
-
-
 /* {{{ php_mysqlnd_cmd_write */
-size_t php_mysqlnd_cmd_write(void * _packet)
+size_t php_mysqlnd_cmd_write(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        /* Let's have some space, which we can use, if not enough, we will allocate new buffer */
        MYSQLND_PACKET_COMMAND * packet= (MYSQLND_PACKET_COMMAND *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        unsigned int error_reporting = EG(error_reporting);
        size_t sent = 0;
 
@@ -1075,28 +1029,16 @@ end:
 /* }}} */
 
 
-/* {{{ php_mysqlnd_cmd_free_mem */
-static
-void php_mysqlnd_cmd_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       if (!stack_allocation) {
-               MYSQLND_PACKET_COMMAND * p = (MYSQLND_PACKET_COMMAND *) _packet;
-               mnd_pefree(p, p->header.persistent);
-       }
-}
-/* }}} */
-
-
 /* {{{ php_mysqlnd_rset_header_read */
 static enum_func_status
-php_mysqlnd_rset_header_read(void * _packet)
+php_mysqlnd_rset_header_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_RSET_HEADER * packet= (MYSQLND_PACKET_RSET_HEADER *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        enum_func_status ret = PASS;
        size_t buf_len = pfc->cmd_buffer.length;
        zend_uchar * buf = (zend_uchar *) pfc->cmd_buffer.buffer;
@@ -1200,7 +1142,7 @@ premature_end:
 
 /* {{{ php_mysqlnd_rset_header_free_mem */
 static
-void php_mysqlnd_rset_header_free_mem(void * _packet, zend_bool stack_allocation)
+void php_mysqlnd_rset_header_free_mem(void * _packet)
 {
        MYSQLND_PACKET_RSET_HEADER *p= (MYSQLND_PACKET_RSET_HEADER *) _packet;
        DBG_ENTER("php_mysqlnd_rset_header_free_mem");
@@ -1208,9 +1150,6 @@ void php_mysqlnd_rset_header_free_mem(void * _packet, zend_bool stack_allocation
                mnd_efree(p->info_or_local_file.s);
                p->info_or_local_file.s = NULL;
        }
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
        DBG_VOID_RETURN;
 }
 /* }}} */
@@ -1234,15 +1173,15 @@ static size_t rset_field_offsets[] =
 
 /* {{{ php_mysqlnd_rset_field_read */
 static enum_func_status
-php_mysqlnd_rset_field_read(void * _packet)
+php_mysqlnd_rset_field_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        /* Should be enough for the metadata of a single row */
        MYSQLND_PACKET_RES_FIELD *packet = (MYSQLND_PACKET_RES_FIELD *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        size_t buf_len = pfc->cmd_buffer.length, total_len = 0;
        zend_uchar * buf = (zend_uchar *) pfc->cmd_buffer.buffer;
        const zend_uchar * p = buf;
@@ -1439,19 +1378,6 @@ premature_end:
 /* }}} */
 
 
-/* {{{ php_mysqlnd_rset_field_free_mem */
-static
-void php_mysqlnd_rset_field_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       MYSQLND_PACKET_RES_FIELD *p = (MYSQLND_PACKET_RES_FIELD *) _packet;
-       /* p->metadata was passed to us as temporal buffer */
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
-}
-/* }}} */
-
-
 /* {{{ php_mysqlnd_read_row_ex */
 static enum_func_status
 php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
@@ -1816,13 +1742,13 @@ php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
   if PS => packet->fields is passed from outside
 */
 static enum_func_status
-php_mysqlnd_rowp_read(void * _packet)
+php_mysqlnd_rowp_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_ROW *packet= (MYSQLND_PACKET_ROW *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
        zend_uchar *p;
        enum_func_status ret = PASS;
        size_t data_size = 0;
@@ -1912,7 +1838,7 @@ end:
 
 /* {{{ php_mysqlnd_rowp_free_mem */
 static void
-php_mysqlnd_rowp_free_mem(void * _packet, zend_bool stack_allocation)
+php_mysqlnd_rowp_free_mem(void * _packet)
 {
        MYSQLND_PACKET_ROW *p;
 
@@ -1922,7 +1848,6 @@ php_mysqlnd_rowp_free_mem(void * _packet, zend_bool stack_allocation)
                p->result_set_memory_pool->free_chunk(p->result_set_memory_pool, p->row_buffer);
                p->row_buffer = NULL;
        }
-       DBG_INF_FMT("stack_allocation=%u persistent=%u", (int)stack_allocation, (int)p->header.persistent);
        /*
          Don't free packet->fields :
          - normal queries -> store_result() | fetch_row_unbuffered() will transfer
@@ -1930,9 +1855,6 @@ php_mysqlnd_rowp_free_mem(void * _packet, zend_bool stack_allocation)
          - PS will pass in it the bound variables, we have to use them! and of course
            not free the array. As it is passed to us, we should not clean it ourselves.
        */
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
        DBG_VOID_RETURN;
 }
 /* }}} */
@@ -1940,14 +1862,14 @@ php_mysqlnd_rowp_free_mem(void * _packet, zend_bool stack_allocation)
 
 /* {{{ php_mysqlnd_stats_read */
 static enum_func_status
-php_mysqlnd_stats_read(void * _packet)
+php_mysqlnd_stats_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_STATS *packet= (MYSQLND_PACKET_STATS *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        size_t buf_len = pfc->cmd_buffer.length;
        zend_uchar *buf = (zend_uchar *) pfc->cmd_buffer.buffer;
 
@@ -1969,16 +1891,13 @@ php_mysqlnd_stats_read(void * _packet)
 
 /* {{{ php_mysqlnd_stats_free_mem */
 static
-void php_mysqlnd_stats_free_mem(void * _packet, zend_bool stack_allocation)
+void php_mysqlnd_stats_free_mem(void * _packet)
 {
        MYSQLND_PACKET_STATS *p= (MYSQLND_PACKET_STATS *) _packet;
        if (p->message.s) {
                mnd_efree(p->message.s);
                p->message.s = NULL;
        }
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
 }
 /* }}} */
 
@@ -1989,14 +1908,14 @@ void php_mysqlnd_stats_free_mem(void * _packet, zend_bool stack_allocation)
 
 /* {{{ php_mysqlnd_prepare_read */
 static enum_func_status
-php_mysqlnd_prepare_read(void * _packet)
+php_mysqlnd_prepare_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_PREPARE_RESPONSE *packet= (MYSQLND_PACKET_PREPARE_RESPONSE *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        /* In case of an error, we should have place to put it */
        size_t buf_len = pfc->cmd_buffer.length;
        zend_uchar *buf = (zend_uchar *) pfc->cmd_buffer.buffer;
@@ -2070,28 +1989,16 @@ premature_end:
 /* }}} */
 
 
-/* {{{ php_mysqlnd_prepare_free_mem */
-static void
-php_mysqlnd_prepare_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       MYSQLND_PACKET_PREPARE_RESPONSE *p= (MYSQLND_PACKET_PREPARE_RESPONSE *) _packet;
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
-}
-/* }}} */
-
-
 /* {{{ php_mysqlnd_chg_user_read */
 static enum_func_status
-php_mysqlnd_chg_user_read(void * _packet)
+php_mysqlnd_chg_user_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_CHG_USER_RESPONSE *packet= (MYSQLND_PACKET_CHG_USER_RESPONSE *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        /* There could be an error message */
        size_t buf_len = pfc->cmd_buffer.length;
        zend_uchar *buf = (zend_uchar *) pfc->cmd_buffer.buffer;
@@ -2154,7 +2061,7 @@ premature_end:
 
 /* {{{ php_mysqlnd_chg_user_free_mem */
 static void
-php_mysqlnd_chg_user_free_mem(void * _packet, zend_bool stack_allocation)
+php_mysqlnd_chg_user_free_mem(void * _packet)
 {
        MYSQLND_PACKET_CHG_USER_RESPONSE * p = (MYSQLND_PACKET_CHG_USER_RESPONSE *) _packet;
 
@@ -2169,23 +2076,18 @@ php_mysqlnd_chg_user_free_mem(void * _packet, zend_bool stack_allocation)
                p->new_auth_protocol_data = NULL;
        }
        p->new_auth_protocol_data_len = 0;
-
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
 }
 /* }}} */
 
 
 /* {{{ php_mysqlnd_sha256_pk_request_write */
 static
-size_t php_mysqlnd_sha256_pk_request_write(void * _packet)
+size_t php_mysqlnd_sha256_pk_request_write(MYSQLND_CONN_DATA * conn, void * _packet)
 {
-       MYSQLND_PACKET_SHA256_PK_REQUEST * packet = (MYSQLND_PACKET_SHA256_PK_REQUEST *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
        zend_uchar buffer[MYSQLND_HEADER_SIZE + 1];
        size_t sent;
 
@@ -2199,30 +2101,18 @@ size_t php_mysqlnd_sha256_pk_request_write(void * _packet)
 /* }}} */
 
 
-/* {{{ php_mysqlnd_sha256_pk_request_free_mem */
-static
-void php_mysqlnd_sha256_pk_request_free_mem(void * _packet, zend_bool stack_allocation)
-{
-       if (!stack_allocation) {
-               MYSQLND_PACKET_SHA256_PK_REQUEST * p = (MYSQLND_PACKET_SHA256_PK_REQUEST *) _packet;
-               mnd_pefree(p, p->header.persistent);
-       }
-}
-/* }}} */
-
-
 #define SHA256_PK_REQUEST_RESP_BUFFER_SIZE 2048
 
 /* {{{ php_mysqlnd_sha256_pk_request_response_read */
 static enum_func_status
-php_mysqlnd_sha256_pk_request_response_read(void * _packet)
+php_mysqlnd_sha256_pk_request_response_read(MYSQLND_CONN_DATA * conn, void * _packet)
 {
        MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * packet= (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet;
-       MYSQLND_ERROR_INFO * error_info = packet->header.error_info;
-       MYSQLND_PFC * pfc = packet->header.protocol_frame_codec;
-       MYSQLND_VIO * vio = packet->header.vio;
-       MYSQLND_STATS * stats = packet->header.stats;
-       MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state;
+       MYSQLND_ERROR_INFO * error_info = conn->error_info;
+       MYSQLND_PFC * pfc = conn->protocol_frame_codec;
+       MYSQLND_VIO * vio = conn->vio;
+       MYSQLND_STATS * stats = conn->stats;
+       MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
        zend_uchar buf[SHA256_PK_REQUEST_RESP_BUFFER_SIZE];
        zend_uchar *p = buf;
        const zend_uchar * const begin = buf;
@@ -2256,7 +2146,7 @@ premature_end:
 
 /* {{{ php_mysqlnd_sha256_pk_request_response_free_mem */
 static void
-php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet, zend_bool stack_allocation)
+php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet)
 {
        MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * p = (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet;
        if (p->public_key) {
@@ -2264,10 +2154,6 @@ php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet, zend_bool stack_
                p->public_key = NULL;
        }
        p->public_key_len = 0;
-
-       if (!stack_allocation) {
-               mnd_pefree(p, p->header.persistent);
-       }
 }
 /* }}} */
 
@@ -2277,91 +2163,76 @@ static
 mysqlnd_packet_methods packet_methods[PROT_LAST] =
 {
        {
-               sizeof(MYSQLND_PACKET_GREET),
                php_mysqlnd_greet_read,
                NULL, /* write */
                php_mysqlnd_greet_free_mem,
        }, /* PROT_GREET_PACKET */
        {
-               sizeof(MYSQLND_PACKET_AUTH),
                NULL, /* read */
                php_mysqlnd_auth_write,
-               php_mysqlnd_auth_free_mem,
+               NULL,
        }, /* PROT_AUTH_PACKET */
        {
-               sizeof(MYSQLND_PACKET_AUTH_RESPONSE),
                php_mysqlnd_auth_response_read, /* read */
                NULL, /* write */
                php_mysqlnd_auth_response_free_mem,
        }, /* PROT_AUTH_RESP_PACKET */
        {
-               sizeof(MYSQLND_PACKET_CHANGE_AUTH_RESPONSE),
                NULL, /* read */
                php_mysqlnd_change_auth_response_write, /* write */
-               php_mysqlnd_change_auth_response_free_mem,
+               NULL,
        }, /* PROT_CHANGE_AUTH_RESP_PACKET */
        {
-               sizeof(MYSQLND_PACKET_OK),
                php_mysqlnd_ok_read, /* read */
                NULL, /* write */
                php_mysqlnd_ok_free_mem,
        }, /* PROT_OK_PACKET */
        {
-               sizeof(MYSQLND_PACKET_EOF),
                php_mysqlnd_eof_read, /* read */
                NULL, /* write */
-               php_mysqlnd_eof_free_mem,
+               NULL,
        }, /* PROT_EOF_PACKET */
        {
-               sizeof(MYSQLND_PACKET_COMMAND),
                NULL, /* read */
                php_mysqlnd_cmd_write, /* write */
-               php_mysqlnd_cmd_free_mem,
+               NULL,
        }, /* PROT_CMD_PACKET */
        {
-               sizeof(MYSQLND_PACKET_RSET_HEADER),
                php_mysqlnd_rset_header_read, /* read */
                NULL, /* write */
                php_mysqlnd_rset_header_free_mem,
        }, /* PROT_RSET_HEADER_PACKET */
        {
-               sizeof(MYSQLND_PACKET_RES_FIELD),
                php_mysqlnd_rset_field_read, /* read */
                NULL, /* write */
-               php_mysqlnd_rset_field_free_mem,
+               NULL,
        }, /* PROT_RSET_FLD_PACKET */
        {
-               sizeof(MYSQLND_PACKET_ROW),
                php_mysqlnd_rowp_read, /* read */
                NULL, /* write */
                php_mysqlnd_rowp_free_mem,
        }, /* PROT_ROW_PACKET */
        {
-               sizeof(MYSQLND_PACKET_STATS),
                php_mysqlnd_stats_read, /* read */
                NULL, /* write */
                php_mysqlnd_stats_free_mem,
        }, /* PROT_STATS_PACKET */
        {
-               sizeof(MYSQLND_PACKET_PREPARE_RESPONSE),
                php_mysqlnd_prepare_read, /* read */
                NULL, /* write */
-               php_mysqlnd_prepare_free_mem,
+               NULL,
        }, /* PROT_PREPARE_RESP_PACKET */
        {
-               sizeof(MYSQLND_PACKET_CHG_USER_RESPONSE),
                php_mysqlnd_chg_user_read, /* read */
                NULL, /* write */
                php_mysqlnd_chg_user_free_mem,
        }, /* PROT_CHG_USER_RESP_PACKET */
        {
-               sizeof(MYSQLND_PACKET_SHA256_PK_REQUEST),
                NULL, /* read */
                php_mysqlnd_sha256_pk_request_write,
-               php_mysqlnd_sha256_pk_request_free_mem,
+               NULL,
        }, /* PROT_SHA256_PK_REQUEST_PACKET */
        {
-               sizeof(MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE),
                php_mysqlnd_sha256_pk_request_response_read,
                NULL, /* write */
                php_mysqlnd_sha256_pk_request_response_free_mem,
@@ -2370,349 +2241,182 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] =
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_greet_packet */
-static struct st_mysqlnd_packet_greet *
-MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_greet_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_greet_packet)(struct st_mysqlnd_packet_greet *packet)
 {
-       struct st_mysqlnd_packet_greet * packet = mnd_pecalloc(1, packet_methods[PROT_GREET_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_greet_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_GREET_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_greet_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_GREET_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_auth_packet */
-static struct st_mysqlnd_packet_auth *
-MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_auth_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_auth_packet)(struct st_mysqlnd_packet_auth *packet)
 {
-       struct st_mysqlnd_packet_auth * packet = mnd_pecalloc(1, packet_methods[PROT_AUTH_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_auth_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_AUTH_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.conn = factory->conn;
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_auth_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_AUTH_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_auth_response_packet */
-static struct st_mysqlnd_packet_auth_response *
-MYSQLND_METHOD(mysqlnd_protocol, get_auth_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_auth_response_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_auth_response_packet)(struct st_mysqlnd_packet_auth_response *packet)
 {
-       struct st_mysqlnd_packet_auth_response * packet = mnd_pecalloc(1, packet_methods[PROT_AUTH_RESP_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_auth_response_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_AUTH_RESP_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_auth_response_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_AUTH_RESP_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_change_auth_response_packet */
-static struct st_mysqlnd_packet_change_auth_response *
-MYSQLND_METHOD(mysqlnd_protocol, get_change_auth_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_change_auth_response_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_change_auth_response_packet)(struct st_mysqlnd_packet_change_auth_response *packet)
 {
-       struct st_mysqlnd_packet_change_auth_response * packet = mnd_pecalloc(1, packet_methods[PROT_CHANGE_AUTH_RESP_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_change_auth_response_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_CHANGE_AUTH_RESP_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_change_auth_response_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_CHANGE_AUTH_RESP_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_ok_packet */
-static struct st_mysqlnd_packet_ok *
-MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_ok_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_ok_packet)(struct st_mysqlnd_packet_ok *packet)
 {
-       struct st_mysqlnd_packet_ok * packet = mnd_pecalloc(1, packet_methods[PROT_OK_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_ok_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_OK_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_ok_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_OK_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_eof_packet */
-static struct st_mysqlnd_packet_eof *
-MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_eof_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_eof_packet)(struct st_mysqlnd_packet_eof *packet)
 {
-       struct st_mysqlnd_packet_eof * packet = mnd_pecalloc(1, packet_methods[PROT_EOF_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_eof_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_EOF_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_eof_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_EOF_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_command_packet */
-static struct st_mysqlnd_packet_command *
-MYSQLND_METHOD(mysqlnd_protocol, get_command_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_command_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_command_packet)(struct st_mysqlnd_packet_command *packet)
 {
-       struct st_mysqlnd_packet_command * packet = mnd_pecalloc(1, packet_methods[PROT_CMD_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_command_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_CMD_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_command_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_CMD_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_rset_packet */
-static struct st_mysqlnd_packet_rset_header *
-MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_rset_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_rset_header_packet)(struct st_mysqlnd_packet_rset_header *packet)
 {
-       struct st_mysqlnd_packet_rset_header * packet = mnd_pecalloc(1, packet_methods[PROT_RSET_HEADER_PACKET].struct_size, persistent);
        DBG_ENTER("mysqlnd_protocol::get_rset_header_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_RSET_HEADER_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_RSET_HEADER_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_result_field_packet */
-static struct st_mysqlnd_packet_res_field *
-MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_result_field_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_result_field_packet)(struct st_mysqlnd_packet_res_field *packet)
 {
-       struct st_mysqlnd_packet_res_field * packet = mnd_pecalloc(1, packet_methods[PROT_RSET_FLD_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_result_field_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_RSET_FLD_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_result_field_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_RSET_FLD_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_row_packet */
-static struct st_mysqlnd_packet_row *
-MYSQLND_METHOD(mysqlnd_protocol, get_row_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_row_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_row_packet)(struct st_mysqlnd_packet_row *packet)
 {
-       struct st_mysqlnd_packet_row * packet = mnd_pecalloc(1, packet_methods[PROT_ROW_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_row_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_ROW_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.conn = factory->conn;
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_row_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_ROW_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_stats_packet */
-static struct st_mysqlnd_packet_stats *
-MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_stats_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_stats_packet)(struct st_mysqlnd_packet_stats *packet)
 {
-       struct st_mysqlnd_packet_stats * packet = mnd_pecalloc(1, packet_methods[PROT_STATS_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_stats_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_STATS_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_stats_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_STATS_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_prepare_response_packet */
-static struct st_mysqlnd_packet_prepare_response *
-MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_prepare_response_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_prepare_response_packet)(struct st_mysqlnd_packet_prepare_response *packet)
 {
-       struct st_mysqlnd_packet_prepare_response * packet = mnd_pecalloc(1, packet_methods[PROT_PREPARE_RESP_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_prepare_response_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_PREPARE_RESP_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_prepare_response_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_PREPARE_RESP_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_change_user_response_packet */
-static struct st_mysqlnd_packet_chg_user_resp*
-MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_change_user_response_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_change_user_response_packet)(struct st_mysqlnd_packet_chg_user_resp *packet)
 {
-       struct st_mysqlnd_packet_chg_user_resp * packet = mnd_pecalloc(1, packet_methods[PROT_CHG_USER_RESP_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_change_user_response_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_CHG_USER_RESP_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_change_user_response_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_CHG_USER_RESP_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_sha256_pk_request_packet */
-static struct st_mysqlnd_packet_sha256_pk_request *
-MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_sha256_pk_request_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_packet)(struct st_mysqlnd_packet_sha256_pk_request *packet)
 {
-       struct st_mysqlnd_packet_sha256_pk_request * packet = mnd_pecalloc(1, packet_methods[PROT_SHA256_PK_REQUEST_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_sha256_pk_request_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_sha256_pk_request_packet");
+       memset(packet, 0, sizeof(*packet));
+       packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_PACKET];
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
 
-/* {{{ mysqlnd_protocol::get_sha256_pk_request_response_packet */
-static struct st_mysqlnd_packet_sha256_pk_request_response *
-MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent)
+/* {{{ mysqlnd_protocol::init_sha256_pk_request_response_packet */
+static void
+MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_response_packet)(struct st_mysqlnd_packet_sha256_pk_request_response *packet)
 {
-       struct st_mysqlnd_packet_sha256_pk_request_response * packet = mnd_pecalloc(1, packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET].struct_size, persistent);
-       DBG_ENTER("mysqlnd_protocol::get_sha256_pk_request_response_packet");
-       if (packet) {
-               packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET];
-               packet->header.factory = factory;
-
-               packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec;
-               packet->header.vio = factory->conn->vio;
-               packet->header.stats = factory->conn->stats;
-               packet->header.error_info = factory->conn->error_info;
-               packet->header.connection_state = &factory->conn->state;
-
-               packet->header.persistent = persistent;
-       }
-       DBG_RETURN(packet);
+       DBG_ENTER("mysqlnd_protocol::init_sha256_pk_request_response_packet");
+       packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET];
+       memset(packet, 0, sizeof(*packet));
+       DBG_VOID_RETURN;
 }
 /* }}} */
 
@@ -2733,7 +2437,7 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command)(
                void * send_close_ctx)
 {
        enum_func_status ret = PASS;
-       MYSQLND_PACKET_COMMAND * cmd_packet = NULL;
+       MYSQLND_PACKET_COMMAND cmd_packet;
        enum mysqlnd_connection_state state;
        DBG_ENTER("mysqlnd_protocol::send_command");
        DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
@@ -2757,21 +2461,17 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command)(
        UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
        SET_EMPTY_ERROR(error_info);
 
-       cmd_packet = payload_decoder_factory->m.get_command_packet(payload_decoder_factory, FALSE);
-       if (!cmd_packet) {
-               SET_OOM_ERROR(error_info);
-               DBG_RETURN(FAIL);
-       }
+       payload_decoder_factory->m.init_command_packet(&cmd_packet);
 
-       cmd_packet->command = command;
+       cmd_packet.command = command;
        if (arg && arg_len) {
-               cmd_packet->argument.s = (char *) arg;
-               cmd_packet->argument.l = arg_len;
+               cmd_packet.argument.s = (char *) arg;
+               cmd_packet.argument.l = arg_len;
        }
 
        MYSQLND_INC_CONN_STATISTIC(stats, STAT_COM_QUIT + command - 1 /* because of COM_SLEEP */ );
 
-       if (! PACKET_WRITE(cmd_packet)) {
+       if (! PACKET_WRITE(payload_decoder_factory->conn, &cmd_packet)) {
                if (!silent) {
                        DBG_ERR_FMT("Error while sending %s packet", mysqlnd_command_to_text[command]);
                        php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid());
@@ -2781,7 +2481,7 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command)(
                DBG_ERR("Server is gone");
                ret = FAIL;
        }
-       PACKET_FREE(cmd_packet);
+       PACKET_FREE(&cmd_packet);
        DBG_RETURN(ret);
 }
 /* }}} */
@@ -2797,22 +2497,19 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_OK)(
                                                MYSQLND_STRING * const last_message)
 {
        enum_func_status ret = FAIL;
-       MYSQLND_PACKET_OK * ok_response = payload_decoder_factory->m.get_ok_packet(payload_decoder_factory, FALSE);
+       MYSQLND_PACKET_OK ok_response;
 
+       payload_decoder_factory->m.init_ok_packet(&ok_response);
        DBG_ENTER("mysqlnd_protocol::send_command_handle_OK");
-       if (!ok_response) {
-               SET_OOM_ERROR(error_info);
-               DBG_RETURN(FAIL);
-       }
-       if (FAIL == (ret = PACKET_READ(ok_response))) {
+       if (FAIL == (ret = PACKET_READ(payload_decoder_factory->conn, &ok_response))) {
                DBG_INF("Error while reading OK packet");
                SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
                goto end;
        }
        DBG_INF_FMT("OK from server");
-       if (0xFF == ok_response->field_count) {
+       if (0xFF == ok_response.field_count) {
                /* The server signalled error. Set the error */
-               SET_CLIENT_ERROR(error_info, ok_response->error_no, ok_response->sqlstate, ok_response->error);
+               SET_CLIENT_ERROR(error_info, ok_response.error_no, ok_response.sqlstate, ok_response.error);
                ret = FAIL;
                /*
                  Cover a protocol design error: error packet does not
@@ -2827,19 +2524,19 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_OK)(
                UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
        } else {
                SET_NEW_MESSAGE(last_message->s, last_message->l,
-                                               ok_response->message, ok_response->message_len);
+                                               ok_response.message, ok_response.message_len);
                if (!ignore_upsert_status) {
                        UPSERT_STATUS_RESET(upsert_status);
-                       UPSERT_STATUS_SET_WARNINGS(upsert_status, ok_response->warning_count);
-                       UPSERT_STATUS_SET_SERVER_STATUS(upsert_status, ok_response->server_status);
-                       UPSERT_STATUS_SET_AFFECTED_ROWS(upsert_status, ok_response->affected_rows);
-                       UPSERT_STATUS_SET_LAST_INSERT_ID(upsert_status, ok_response->last_insert_id);
+                       UPSERT_STATUS_SET_WARNINGS(upsert_status, ok_response.warning_count);
+                       UPSERT_STATUS_SET_SERVER_STATUS(upsert_status, ok_response.server_status);
+                       UPSERT_STATUS_SET_AFFECTED_ROWS(upsert_status, ok_response.affected_rows);
+                       UPSERT_STATUS_SET_LAST_INSERT_ID(upsert_status, ok_response.last_insert_id);
                } else {
                        /* LOAD DATA */
                }
        }
 end:
-       PACKET_FREE(ok_response);
+       PACKET_FREE(&ok_response);
        DBG_INF(ret == PASS ? "PASS":"FAIL");
        DBG_RETURN(ret);
 }
@@ -2854,32 +2551,30 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_EOF)(
                                                MYSQLND_UPSERT_STATUS * const upsert_status)
 {
        enum_func_status ret = FAIL;
-       MYSQLND_PACKET_EOF * response = payload_decoder_factory->m.get_eof_packet(payload_decoder_factory, FALSE);
+       MYSQLND_PACKET_EOF response;
+
+       payload_decoder_factory->m.init_eof_packet(&response);
 
        DBG_ENTER("mysqlnd_protocol::send_command_handle_EOF");
 
-       if (!response) {
-               SET_OOM_ERROR(error_info);
-               DBG_RETURN(FAIL);
-       }
-       if (FAIL == (ret = PACKET_READ(response))) {
+       if (FAIL == (ret = PACKET_READ(payload_decoder_factory->conn, &response))) {
                DBG_INF("Error while reading EOF packet");
                SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
-       } else if (0xFF == response->field_count) {
+       } else if (0xFF == response.field_count) {
                /* The server signalled error. Set the error */
-               DBG_INF_FMT("Error_no=%d SQLstate=%s Error=%s", response->error_no, response->sqlstate, response->error);
+               DBG_INF_FMT("Error_no=%d SQLstate=%s Error=%s", response.error_no, response.sqlstate, response.error);
 
-               SET_CLIENT_ERROR(error_info, response->error_no, response->sqlstate, response->error);
+               SET_CLIENT_ERROR(error_info, response.error_no, response.sqlstate, response.error);
 
                UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(upsert_status);
-       } else if (0xFE != response->field_count) {
+       } else if (0xFE != response.field_count) {
                SET_CLIENT_ERROR(error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "Malformed packet");
-               DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", response->field_count);
-               php_error_docref(NULL, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X", response->field_count);
+               DBG_ERR_FMT("EOF packet expected, field count wasn't 0xFE but 0x%2X", response.field_count);
+               php_error_docref(NULL, E_WARNING, "EOF packet expected, field count wasn't 0xFE but 0x%2X", response.field_count);
        } else {
                DBG_INF_FMT("EOF from server");
        }
-       PACKET_FREE(response);
+       PACKET_FREE(&response);
 
        DBG_INF(ret == PASS ? "PASS":"FAIL");
        DBG_RETURN(ret);
@@ -2928,21 +2623,21 @@ MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_response)(
 
 
 MYSQLND_CLASS_METHODS_START(mysqlnd_protocol_payload_decoder_factory)
-       MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_auth_response_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_change_auth_response_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_command_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_row_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet),
-       MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_greet_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_auth_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_auth_response_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_change_auth_response_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_ok_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_command_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_eof_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_rset_header_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_result_field_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_row_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_stats_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_prepare_response_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_change_user_response_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_packet),
+       MYSQLND_METHOD(mysqlnd_protocol, init_sha256_pk_request_response_packet),
 
        MYSQLND_METHOD(mysqlnd_protocol, send_command),
        MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_response),
index ad6aa524098f9a553fe1d5f6b217f63af43b6dcc..024f12e2a6c917fd804816708df2001564fb9fc3 100644 (file)
@@ -31,13 +31,13 @@ PHPAPI extern const char mysqlnd_read_body_name[];
 
 
 /* Packet handling */
-#define PACKET_WRITE(packet)   ((packet)->header.m->write_to_net((packet)))
-#define PACKET_READ(packet)            ((packet)->header.m->read_from_net((packet)))
+#define PACKET_WRITE(conn, packet)     ((packet)->header.m->write_to_net((conn), (packet)))
+#define PACKET_READ(conn, packet)      ((packet)->header.m->read_from_net((conn), (packet)))
 #define PACKET_FREE(packet) \
        do { \
                DBG_INF_FMT("PACKET_FREE(%p)", packet); \
-               if ((packet)) { \
-                       ((packet)->header.m->free_mem((packet), FALSE)); \
+               if ((packet)->header.m->free_mem) { \
+                       ((packet)->header.m->free_mem((packet))); \
                } \
        } while (0);
 
@@ -45,27 +45,17 @@ PHPAPI extern const char * const mysqlnd_command_to_text[COM_END];
 
 /* Low-level extraction functionality */
 typedef struct st_mysqlnd_packet_methods {
-       size_t                          struct_size;
-       enum_func_status        (*read_from_net)(void * packet);
-       size_t                          (*write_to_net)(void * packet);
-       void                            (*free_mem)(void *packet, zend_bool stack_allocation);
+       enum_func_status        (*read_from_net)(MYSQLND_CONN_DATA * conn, void * packet);
+       size_t                          (*write_to_net)(MYSQLND_CONN_DATA * conn, void * packet);
+       void                            (*free_mem)(void *packet);
 } mysqlnd_packet_methods;
 
 
 typedef struct st_mysqlnd_packet_header {
        size_t          size;
        zend_uchar      packet_no;
-       zend_bool       persistent;
 
        mysqlnd_packet_methods *m;
-
-       MYSQLND_CONN_DATA * conn;
-       MYSQLND_PFC * protocol_frame_codec;
-       MYSQLND_VIO * vio;
-       MYSQLND_ERROR_INFO * error_info;
-       MYSQLND_STATS * stats;
-       MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * factory;
-       MYSQLND_CONNECTION_STATE * connection_state;
 } MYSQLND_PACKET_HEADER;
 
 /* Server greets the client */