Skip to content

Commit

Permalink
MNDR:
Browse files Browse the repository at this point in the history
- make MYSQLND_ERROR_INFO a class
  • Loading branch information
faizshukri committed Nov 12, 2015
1 parent fb1b5ab commit 4bb784c
Show file tree
Hide file tree
Showing 13 changed files with 396 additions and 349 deletions.
250 changes: 138 additions & 112 deletions ext/mysqlnd/mysqlnd.c

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions ext/mysqlnd/mysqlnd_auth.c
Expand Up @@ -60,23 +60,23 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
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);
SET_OOM_ERROR(conn->error_info);
goto end;
}

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);
SET_OOM_ERROR(conn->error_info);
goto end;
}

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, conn)) {
if (!PACKET_WRITE(change_auth_resp_packet)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end;
}
} else {
Expand All @@ -103,20 +103,20 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
auth_packet->connect_attr = conn->options->connect_attr;
}

if (!PACKET_WRITE(auth_packet, conn)) {
if (!PACKET_WRITE(auth_packet)) {
goto end;
}
}
if (use_full_blown_auth_packet == TRUE) {
conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no);
}

if (FAIL == PACKET_READ(auth_resp_packet, conn) || auth_resp_packet->response_code >= 0xFE) {
if (FAIL == PACKET_READ(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) {
DBG_ERR(mysqlnd_old_passwd);
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, 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;
Expand All @@ -134,7 +134,7 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
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;
}
Expand Down Expand Up @@ -181,30 +181,30 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
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);
SET_OOM_ERROR(conn->error_info);
goto end;
}

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);
SET_OOM_ERROR(conn->error_info);
goto end;
}

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, conn)) {
if (!PACKET_WRITE(change_auth_resp_packet)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end;
}
} else {
auth_packet = conn->payload_decoder_factory->m.get_auth_packet(conn->payload_decoder_factory, FALSE);

if (!auth_packet) {
SET_OOM_ERROR(*conn->error_info);
SET_OOM_ERROR(conn->error_info);
goto end;
}

Expand All @@ -223,21 +223,21 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
auth_packet->charset_no = conn->charset->nr;
}

if (!PACKET_WRITE(auth_packet, conn)) {
if (!PACKET_WRITE(auth_packet)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end;
}
}

ret = PACKET_READ(chg_user_resp, conn);
COPY_CLIENT_ERROR(*conn->error_info, chg_user_resp->error_info);
ret = PACKET_READ(chg_user_resp);
COPY_CLIENT_ERROR(conn->error_info, chg_user_resp->error_info);

if (0xFE == chg_user_resp->response_code) {
ret = FAIL;
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);
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;
Expand All @@ -262,11 +262,11 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
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, conn);
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);
SET_OOM_ERROR(conn->error_info);
}
}
}
Expand Down Expand Up @@ -297,7 +297,7 @@ mysqlnd_auth_change_user(MYSQLND_CONN_DATA * const conn,
} 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);
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, mysqlnd_old_passwd);
}
end:
PACKET_FREE(change_auth_resp_packet);
Expand Down Expand Up @@ -371,7 +371,7 @@ mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
/* 5.5.x reports 21 as scramble length because it needs to show the length of the data before the plugin name */
if (auth_plugin_data_len < SCRAMBLE_LENGTH) {
/* mysql_native_password only works with SCRAMBLE_LENGTH scramble */
SET_CLIENT_ERROR(*conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "The server sent wrong length for scramble");
SET_CLIENT_ERROR(conn->error_info, CR_MALFORMED_PACKET, UNKNOWN_SQLSTATE, "The server sent wrong length for scramble");
DBG_ERR_FMT("The server sent wrong length for scramble %u. Expected %u", auth_plugin_data_len, SCRAMBLE_LENGTH);
DBG_RETURN(NULL);
}
Expand Down Expand Up @@ -501,23 +501,23 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
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);
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);
SET_OOM_ERROR(conn->error_info);
PACKET_FREE(pk_req_packet);
break;
}

if (! PACKET_WRITE(pk_req_packet, conn)) {
if (! PACKET_WRITE(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());
CONN_SET_STATE(conn, CONN_QUIT_SENT);
break;
}
if (FAIL == PACKET_READ(pk_resp_packet, conn) || NULL == pk_resp_packet->public_key) {
if (FAIL == PACKET_READ(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());
CONN_SET_STATE(conn, CONN_QUIT_SENT);
Expand All @@ -537,7 +537,7 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("ret=%p", ret);
DBG_RETURN(ret);

SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE,
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE,
"sha256_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key");
DBG_ERR("server_public_key is not set");
DBG_RETURN(NULL);
Expand Down Expand Up @@ -605,7 +605,7 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
*/
if ((size_t) server_public_key_len - 41 <= passwd_len) {
/* password message is to long */
SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
DBG_ERR("password is too long");
DBG_RETURN(NULL);
}
Expand Down
45 changes: 13 additions & 32 deletions ext/mysqlnd/mysqlnd_driver.c
Expand Up @@ -93,22 +93,6 @@ PHPAPI void mysqlnd_library_init(void)
/* }}} */



/* {{{ mysqlnd_error_list_pdtor */
static void
mysqlnd_error_list_pdtor(void * pDest)
{
MYSQLND_ERROR_LIST_ELEMENT * element = (MYSQLND_ERROR_LIST_ELEMENT *) pDest;

DBG_ENTER("mysqlnd_error_list_pdtor");
if (element->error) {
mnd_pefree(element->error, TRUE);
}
DBG_VOID_RETURN;
}
/* }}} */


/* {{{ mysqlnd_object_factory::get_connection */
static MYSQLND *
MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_factory_methods * factory, zend_bool persistent)
Expand All @@ -133,7 +117,12 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_
new_object->m = mysqlnd_conn_get_methods();
data = new_object->data;

data->error_info = &(data->error_info_impl);
if (FAIL == mysqlnd_error_info_init(&data->error_info_impl, persistent)) {
new_object->m->dtor(new_object);
DBG_RETURN(NULL);
}
data->error_info = &data->error_info_impl;

data->options = &(data->options_impl);

mysqlnd_upsert_status_init(&data->upsert_status_impl);
Expand All @@ -146,13 +135,6 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_
CONN_SET_STATE(data, CONN_ALLOCED);
data->m->get_reference(data);

data->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent);
if (!data->error_info->error_list) {
new_object->m->dtor(new_object);
DBG_RETURN(NULL);
}
zend_llist_init(data->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t)mysqlnd_error_list_pdtor, persistent);

mysqlnd_stats_init(&data->stats, STAT_LAST, persistent);

data->net = mysqlnd_net_init(persistent, data->stats, data->error_info);
Expand Down Expand Up @@ -220,7 +202,12 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
break;
}
stmt->persistent = persistent;
stmt->error_info = &(stmt->error_info_impl);

if (FAIL == mysqlnd_error_info_init(&stmt->error_info_impl, persistent)) {
break;
}
stmt->error_info = &stmt->error_info_impl;

mysqlnd_upsert_status_init(&stmt->upsert_status_impl);
stmt->upsert_status = &(stmt->upsert_status_impl);
stmt->state = MYSQLND_STMT_INITTED;
Expand All @@ -231,12 +218,6 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
}

stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS;
stmt->error_info->error_list = mnd_pecalloc(1, sizeof(zend_llist), ret->persistent);
if (!stmt->error_info->error_list) {
break;
}

zend_llist_init(stmt->error_info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, persistent);

/*
Mark that we reference the connection, thus it won't be
Expand All @@ -248,7 +229,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
DBG_RETURN(ret);
} while (0);

SET_OOM_ERROR(*conn->error_info);
SET_OOM_ERROR(conn->error_info);
if (ret) {
ret->m->dtor(ret, TRUE);
ret = NULL;
Expand Down
8 changes: 4 additions & 4 deletions ext/mysqlnd/mysqlnd_loaddata.c
Expand Up @@ -176,7 +176,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
*is_warning = TRUE;
/* error occurred */
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf));
SET_CLIENT_ERROR(*conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
/* write empty packet to server */
ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info);
goto infile_error;
Expand All @@ -186,14 +186,14 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE)) > 0) {
if ((ret = net->data->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info)) == 0) {
DBG_ERR_FMT("Error during read : %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
goto infile_error;
}
}

/* send empty packet for eof */
if ((ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info)) == 0) {
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
goto infile_error;
}

Expand All @@ -204,7 +204,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
*is_warning = TRUE;
DBG_ERR_FMT("Bufsize < 0, warning, %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf));
SET_CLIENT_ERROR(*conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
goto infile_error;
}

Expand Down
8 changes: 4 additions & 4 deletions ext/mysqlnd/mysqlnd_net.c
Expand Up @@ -148,7 +148,7 @@ MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const char * con
streams_options |= IGNORE_URL;
net_stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL);
if (!net_stream) {
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting");
SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting");
DBG_RETURN(NULL);
}
/*
Expand Down Expand Up @@ -211,7 +211,7 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
mnd_sprintf_free(hashed_details);
}
errcode = CR_CONNECTION_ERROR;
SET_CLIENT_ERROR(*error_info,
SET_CLIENT_ERROR(error_info,
CR_CONNECTION_ERROR,
UNKNOWN_SQLSTATE,
errstr? ZSTR_VAL(errstr):"Unknown error while connecting");
Expand Down Expand Up @@ -310,7 +310,7 @@ MYSQLND_METHOD(mysqlnd_net, get_open_stream)(MYSQLND_NET * const net, const char
}

if (!ret) {
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "No handler for this scheme");
SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "No handler for this scheme");
}

DBG_RETURN(ret);
Expand Down Expand Up @@ -484,7 +484,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
/* Even for zero size payload we have to send a packet */
if (!bytes_sent) {
DBG_ERR_FMT("Can't %u send bytes", count);
SET_CLIENT_ERROR(*error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
}
DBG_RETURN(bytes_sent);
}
Expand Down

0 comments on commit 4bb784c

Please sign in to comment.