/* {{{ mysqlnd_native_auth_get_auth_data */ static zend_uchar * mysqlnd_caching_sha2_get_auth_data(struct st_mysqlnd_authentication_plugin * self, size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len, const MYSQLND_SESSION_OPTIONS * const session_options, const MYSQLND_PFC_DATA * const pfc_data, const zend_ulong mysql_flags ) { zend_uchar * ret = NULL; DBG_ENTER("mysqlnd_caching_sha2_get_auth_data"); DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data); *auth_data_len = 0; DBG_INF("First auth step: send hashed password"); /* copy scrambled pass*/ if (passwd && passwd_len) { ret = malloc(SHA256_LENGTH + 1); *auth_data_len = SHA256_LENGTH; php_mysqlnd_scramble_sha2((zend_uchar*)ret, auth_plugin_data, (zend_uchar*)passwd, passwd_len); ret[SHA256_LENGTH] = '\0'; DBG_INF_FMT("hash(%d)=[%.*s]", *auth_data_len, *auth_data_len, ret); } DBG_RETURN(ret); }
/* {{{ mysqlnd_result_meta_init */ PHPAPI MYSQLND_RES_METADATA * mysqlnd_result_meta_init(unsigned int field_count, zend_bool persistent) { size_t alloc_size = sizeof(MYSQLND_RES_METADATA) + mysqlnd_plugin_count() * sizeof(void *); MYSQLND_RES_METADATA *ret = mnd_pecalloc(1, alloc_size, persistent); DBG_ENTER("mysqlnd_result_meta_init"); DBG_INF_FMT("persistent=%u", persistent); do { if (!ret) { break; } ret->m = & mysqlnd_mysqlnd_res_meta_methods; ret->persistent = persistent; ret->field_count = field_count; /* +1 is to have empty marker at the end */ ret->fields = mnd_pecalloc(field_count + 1, sizeof(MYSQLND_FIELD), ret->persistent); ret->zend_hash_keys = mnd_pecalloc(field_count, sizeof(struct mysqlnd_field_hash_key), ret->persistent); if (!ret->fields || !ret->zend_hash_keys) { break; } DBG_INF_FMT("meta=%p", ret); DBG_RETURN(ret); } while (0); if (ret) { ret->m->free_metadata(ret); } DBG_RETURN(NULL); }
/* {{{ _mysqlnd_emalloc */ void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D) { void *ret; zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); #if PHP_DEBUG long * threshold = &MYSQLND_G(debug_emalloc_fail_threshold); #endif DBG_ENTER(mysqlnd_emalloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); #if PHP_DEBUG /* -1 is also "true" */ if (*threshold) { #endif ret = emalloc(REAL_SIZE(size)); #if PHP_DEBUG --*threshold; } else if (*threshold == 0) { ret = NULL; } #endif DBG_INF_FMT("size=%lu ptr=%p", size, ret); if (ret && collect_memory_statistics) { *(size_t *) ret = size; MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EMALLOC_COUNT, 1, STAT_MEM_EMALLOC_AMOUNT, size); } DBG_RETURN(FAKE_PTR(ret)); }
/* {{{ ps_fetch_string */ static void ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { /* For now just copy, before we make it possible to write \0 to the row buffer */ unsigned long length = php_mysqlnd_net_field_length(row); DBG_ENTER("ps_fetch_string"); DBG_INF_FMT("len = %lu", length); #if PHP_MAJOR_VERSION < 6 DBG_INF("copying from the row buffer"); ZVAL_STRINGL(zv, (char *)*row, length, 1); #else if (field->charsetnr == MYSQLND_BINARY_CHARSET_NR) { DBG_INF("Binary charset"); ZVAL_STRINGL(zv, (char *)*row, length, 1); } else { DBG_INF_FMT("copying from the row buffer"); ZVAL_UTF8_STRINGL(zv, (char*)*row, length, ZSTR_DUPLICATE); } #endif (*row) += length; DBG_VOID_RETURN; }
/* {{{ _mysqlnd_pecalloc */ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent MYSQLND_MEM_D) { void *ret; zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); #if PHP_DEBUG long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold); #endif DBG_ENTER(mysqlnd_pecalloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); #if PHP_DEBUG /* -1 is also "true" */ if (*threshold) { #endif ret = pecalloc(nmemb, REAL_SIZE(size), persistent); #if PHP_DEBUG --*threshold; } else if (*threshold == 0) { ret = NULL; } #endif DBG_INF_FMT("size=%lu ptr=%p", size, ret); if (ret && collect_memory_statistics) { enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT; enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_CALLOC_AMOUNT:STAT_MEM_ECALLOC_AMOUNT; *(size_t *) ret = size; MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size); } DBG_RETURN(FAKE_PTR(ret)); }
/* {{{ _mysqlnd_perealloc */ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQLND_MEM_D) { void *ret; zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics); size_t old_size = collect_memory_statistics && ptr? *(size_t *) (((char*)ptr) - sizeof(size_t)) : 0; #if PHP_DEBUG long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold); #endif DBG_ENTER(mysqlnd_perealloc_name); DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno); DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent); #if PHP_DEBUG /* -1 is also "true" */ if (*threshold) { #endif ret = perealloc(REAL_PTR(ptr), REAL_SIZE(new_size), persistent); #if PHP_DEBUG --*threshold; } else if (*threshold == 0) { ret = NULL; } #endif DBG_INF_FMT("new_ptr=%p", (char*)ret); if (ret && collect_memory_statistics) { enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT; enum mysqlnd_collected_stats s2 = persistent? STAT_MEM_REALLOC_AMOUNT:STAT_MEM_EREALLOC_AMOUNT; *(size_t *) ret = new_size; MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size); } DBG_RETURN(FAKE_PTR(ret)); }
/* {{{ mysqlnd_res_meta::fetch_field_direct */ static const MYSQLND_FIELD * MYSQLND_METHOD(mysqlnd_res_meta, fetch_field_direct)(const MYSQLND_RES_METADATA * const meta, const MYSQLND_FIELD_OFFSET fieldnr) { DBG_ENTER("mysqlnd_res_meta::fetch_field_direct"); DBG_INF_FMT("fieldnr=%u", fieldnr); DBG_INF_FMT("name=%s max_length=%u", meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"", meta->fields[meta->current_field].max_length); DBG_RETURN(&meta->fields[fieldnr]); }
/* {{{ mysqlnd_res_meta::free */ static void MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA * meta) { int i; MYSQLND_FIELD *fields; DBG_ENTER("mysqlnd_res_meta::free"); DBG_INF_FMT("persistent=%u", meta->persistent); if ((fields = meta->fields)) { DBG_INF("Freeing fields metadata"); i = meta->field_count; while (i--) { php_mysqlnd_free_field_metadata(fields++, meta->persistent); } mnd_pefree(meta->fields, meta->persistent); meta->fields = NULL; } if (meta->zend_hash_keys) { DBG_INF("Freeing zend_hash_keys"); mnd_pefree(meta->zend_hash_keys, meta->persistent); meta->zend_hash_keys = NULL; } DBG_INF("Freeing metadata structure"); mnd_pefree(meta, meta->persistent); DBG_VOID_RETURN; }
/* {{{ mysqlnd_object_factory::get_io_channel */ PHPAPI MYSQLND_NET * MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info) { size_t net_alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *); size_t net_data_alloc_size = sizeof(MYSQLND_NET_DATA) + mysqlnd_plugin_count() * sizeof(void *); MYSQLND_NET * net = mnd_pecalloc(1, net_alloc_size, persistent); MYSQLND_NET_DATA * net_data = mnd_pecalloc(1, net_data_alloc_size, persistent); DBG_ENTER("mysqlnd_object_factory::get_io_channel"); DBG_INF_FMT("persistent=%u", persistent); if (net && net_data) { net->data = net_data; net->persistent = net->data->persistent = persistent; net->data->m = *mysqlnd_net_get_methods(); if (PASS != net->data->m.init(net, stats, error_info)) { net->data->m.dtor(net, stats, error_info); net = NULL; } } else { if (net_data) { mnd_pefree(net_data, persistent); net_data = NULL; } if (net) { mnd_pefree(net, persistent); net = NULL; } } DBG_RETURN(net); }
/* {{{ mysqlnd_object_factory::clone_connection_object */ static MYSQLND * MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object)(MYSQLND * to_be_cloned) { size_t alloc_size_ret = sizeof(MYSQLND) + mysqlnd_plugin_count() * sizeof(void *); MYSQLND * new_object; DBG_ENTER("mysqlnd_driver::clone_connection_object"); DBG_INF_FMT("persistent=%u", to_be_cloned->persistent); if (!to_be_cloned || !to_be_cloned->data) { DBG_RETURN(NULL); } new_object = mnd_pecalloc(1, alloc_size_ret, to_be_cloned->persistent); if (!new_object) { DBG_RETURN(NULL); } new_object->persistent = to_be_cloned->persistent; new_object->m = to_be_cloned->m; new_object->data = to_be_cloned->data->m->get_reference(to_be_cloned->data); if (!new_object->data) { new_object->m->dtor(new_object); new_object = NULL; } DBG_RETURN(new_object); }
/* {{{ mysqlnd_stmt_execute_generate_request */ enum_func_status mysqlnd_stmt_execute_generate_request(MYSQLND_STMT * const s, zend_uchar ** request, size_t *request_len, zend_bool * free_buffer) { MYSQLND_STMT_DATA * stmt = s->data; zend_uchar *p = stmt->execute_cmd_buffer.buffer, *cmd_buffer = stmt->execute_cmd_buffer.buffer; size_t cmd_buffer_length = stmt->execute_cmd_buffer.length; enum_func_status ret; DBG_ENTER("mysqlnd_stmt_execute_generate_request"); int4store(p, stmt->stmt_id); p += 4; /* flags is 4 bytes, we store just 1 */ int1store(p, (zend_uchar) stmt->flags); p++; /* Make it all zero */ int4store(p, 0); int1store(p, 1); /* and send 1 for iteration count */ p+= 4; ret = mysqlnd_stmt_execute_store_params(s, &cmd_buffer, &p, &cmd_buffer_length); *free_buffer = (cmd_buffer != stmt->execute_cmd_buffer.buffer); *request_len = (p - cmd_buffer); *request = cmd_buffer; DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"******"); DBG_RETURN(ret); }
/* {{{ ps_fetch_date */ static void ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { struct st_mysqlnd_time t = {0}; zend_ulong length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_date"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type= MYSQLND_TIMESTAMP_DATE; t.neg= 0; t.second_part = t.hour = t.minute = t.second = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATE; } length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day); DBG_INF_FMT("%s", value); ZVAL_STRINGL(zv, value, length); mnd_sprintf_free(value); DBG_VOID_RETURN; }
/* {{{ mysqlnd_vio::post_connect_set_opt */ static void MYSQLND_METHOD(mysqlnd_vio, post_connect_set_opt)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { php_stream * net_stream = vio->data->m.get_stream(vio); DBG_ENTER("mysqlnd_vio::post_connect_set_opt"); if (net_stream) { if (vio->data->options.timeout_read) { struct timeval tv; DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", vio->data->options.timeout_read); tv.tv_sec = vio->data->options.timeout_read; tv.tv_usec = 0; php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv); } if (!memcmp(scheme.s, "tcp://", sizeof("tcp://") - 1)) { /* TCP -> Set TCP_NODELAY */ mysqlnd_set_sock_no_delay(net_stream); /* TCP -> Set SO_KEEPALIVE */ mysqlnd_set_sock_keepalive(net_stream); } } DBG_VOID_RETURN; }
/* {{{ mysqlnd_vio::close_stream */ static void MYSQLND_METHOD(mysqlnd_vio, close_stream)(MYSQLND_VIO * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { php_stream * net_stream; DBG_ENTER("mysqlnd_vio::close_stream"); if (net && (net_stream = net->data->m.get_stream(net))) { zend_bool pers = net->persistent; DBG_INF_FMT("Freeing stream. abstract=%p", net_stream->abstract); if (pers) { if (EG(active)) { php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); } else { /* otherwise we will crash because the EG(persistent_list) has been freed already, before the modules are shut down */ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } } else { php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE); } (void) net->data->m.set_stream(net, NULL); } DBG_VOID_RETURN; }
/* {{{ mysqlnd_vio::network_read */ static enum_func_status MYSQLND_METHOD(mysqlnd_vio, network_read)(MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { enum_func_status return_value = PASS; php_stream * net_stream = vio->data->m.get_stream(vio); size_t old_chunk_size = net_stream->chunk_size; size_t to_read = count, ret; zend_uchar * p = buffer; DBG_ENTER("mysqlnd_vio::network_read"); DBG_INF_FMT("count="MYSQLND_SZ_T_SPEC, count); net_stream->chunk_size = MIN(to_read, vio->data->options.net_read_buffer_size); while (to_read) { if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) { DBG_ERR_FMT("Error while reading header from socket"); return_value = FAIL; break; } p += ret; to_read -= ret; } MYSQLND_INC_CONN_STATISTIC_W_VALUE(stats, STAT_BYTES_RECEIVED, count - to_read); net_stream->chunk_size = old_chunk_size; DBG_RETURN(return_value); }
/* {{{ mysqlnd_vio::has_valid_stream */ static zend_bool MYSQLND_METHOD(mysqlnd_vio, has_valid_stream)(const MYSQLND_VIO * const vio) { DBG_ENTER("mysqlnd_vio::has_valid_stream"); DBG_INF_FMT("%p %p", vio, vio? vio->data->stream:NULL); DBG_RETURN((vio && vio->data->stream)? TRUE: FALSE); }
/* {{{ mysqlnd_vio::get_stream */ static php_stream * MYSQLND_METHOD(mysqlnd_vio, get_stream)(const MYSQLND_VIO * const net) { DBG_ENTER("mysqlnd_vio::get_stream"); DBG_INF_FMT("%p", net? net->data->stream:NULL); DBG_RETURN(net? net->data->stream:NULL); }
/* {{{ mysqlnd_local_infile_error */ static int mysqlnd_local_infile_error(void * ptr, char *error_buf, unsigned int error_buf_len) { MYSQLND_INFILE_INFO *info = (MYSQLND_INFILE_INFO *)ptr; DBG_ENTER("mysqlnd_local_infile_error"); if (info) { strlcpy(error_buf, info->error_msg, error_buf_len); DBG_INF_FMT("have info, %d", info->error_no); DBG_RETURN(info->error_no); } strlcpy(error_buf, "Unknown error", error_buf_len); DBG_INF_FMT("no info, %d", CR_UNKNOWN_ERROR); DBG_RETURN(CR_UNKNOWN_ERROR); }
/* {{{ mysqlnd_vio::network_write */ static size_t MYSQLND_METHOD(mysqlnd_vio, network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { size_t ret; DBG_ENTER("mysqlnd_vio::network_write"); DBG_INF_FMT("sending %u bytes", count); ret = php_stream_write(vio->data->m.get_stream(vio), (char *)buffer, count); DBG_RETURN(ret); }
/* {{{ ps_fetch_datetime */ static void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char *to; DBG_ENTER("ps_fetch_datetime"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_DATETIME; t.neg = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; if (length > 4) { t.hour = (unsigned int) to[4]; t.minute = (unsigned int) to[5]; t.second = (unsigned int) to[6]; } else { t.hour = t.minute = t.second= 0; } t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATETIME; } /* QQ : How to make this unicode without copying two times the buffer - Unicode equivalent of spprintf? */ length = spprintf(&to, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second); DBG_INF_FMT("%s", to); #if PHP_MAJOR_VERSION >= 6 if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); efree(to); /* allocated by spprintf */ #if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; }
/* {{{ mysqlnd_net::decode */ static enum_func_status MYSQLND_METHOD(mysqlnd_net, decode)(zend_uchar * uncompressed_data, const size_t uncompressed_data_len, const zend_uchar * const compressed_data, const size_t compressed_data_len) { #ifdef MYSQLND_COMPRESSION_ENABLED int error; uLongf tmp_complen = uncompressed_data_len; DBG_ENTER("mysqlnd_net::decode"); error = uncompress(uncompressed_data, &tmp_complen, compressed_data, compressed_data_len); DBG_INF_FMT("compressed data: decomp_len=%lu compressed_size="MYSQLND_SZ_T_SPEC, tmp_complen, compressed_data_len); if (error != Z_OK) { DBG_INF_FMT("decompression NOT successful. error=%d Z_OK=%d Z_BUF_ERROR=%d Z_MEM_ERROR=%d", error, Z_OK, Z_BUF_ERROR, Z_MEM_ERROR); } DBG_RETURN(error == Z_OK? PASS:FAIL); #else DBG_ENTER("mysqlnd_net::decode"); DBG_RETURN(FAIL); #endif }
/* {{{ ps_fetch_double */ static void ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row) { double value; DBG_ENTER("ps_fetch_double"); float8get(value, *row); ZVAL_DOUBLE(zv, value); (*row)+= 8; DBG_INF_FMT("value=%f", value); DBG_VOID_RETURN; }
/* {{{ mysqlnd_object_factory::get_prepared_statement */ static MYSQLND_STMT * MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA * const conn) { size_t alloc_size = sizeof(MYSQLND_STMT) + mysqlnd_plugin_count() * sizeof(void *); MYSQLND_STMT * ret = mnd_pecalloc(1, alloc_size, conn->persistent); MYSQLND_STMT_DATA * stmt = NULL; DBG_ENTER("mysqlnd_object_factory::get_prepared_statement"); do { if (!ret) { break; } ret->m = mysqlnd_stmt_get_methods(); ret->persistent = conn->persistent; stmt = ret->data = mnd_pecalloc(1, sizeof(MYSQLND_STMT_DATA), conn->persistent); DBG_INF_FMT("stmt=%p", stmt); if (!stmt) { break; } stmt->persistent = conn->persistent; stmt->error_info = &(stmt->error_info_impl); stmt->upsert_status = &(stmt->upsert_status_impl); stmt->state = MYSQLND_STMT_INITTED; stmt->execute_cmd_buffer.length = 4096; stmt->execute_cmd_buffer.buffer = mnd_pemalloc(stmt->execute_cmd_buffer.length, stmt->persistent); if (!stmt->execute_cmd_buffer.buffer) { break; } stmt->prefetch_rows = MYSQLND_DEFAULT_PREFETCH_ROWS; /* Mark that we reference the connection, thus it won't be be destructed till there is open statements. The last statement or normal query result will close it then. */ stmt->conn = conn->m->get_reference(conn); 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, conn->persistent); DBG_RETURN(ret); } while (0); SET_OOM_ERROR(*conn->error_info); if (ret) { ret->m->dtor(ret, TRUE); ret = NULL; } DBG_RETURN(NULL); }
/* {{{ mysqlnd_sha256_auth_get_auth_data */ static zend_uchar * mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, size_t * auth_data_len, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, const MYSQLND_OPTIONS * const options, const MYSQLND_NET_OPTIONS * const net_options, zend_ulong mysql_flags ) { RSA * server_public_key; zend_uchar * ret = NULL; DBG_ENTER("mysqlnd_sha256_auth_get_auth_data"); DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data); if (conn->net->data->ssl) { DBG_INF("simple clear text under SSL"); /* clear text under SSL */ *auth_data_len = passwd_len; ret = malloc(passwd_len); memcpy(ret, passwd, passwd_len); } else { *auth_data_len = 0; server_public_key = mysqlnd_sha256_get_rsa_key(conn, options, net_options); if (server_public_key) { int server_public_key_len; char xor_str[passwd_len + 1]; memcpy(xor_str, passwd, passwd_len); xor_str[passwd_len] = '\0'; mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len); server_public_key_len = RSA_size(server_public_key); /* Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len. RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here: http://www.openssl.org/docs/crypto/RSA_public_encrypt.html */ 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"); DBG_ERR("password is too long"); DBG_RETURN(NULL); } *auth_data_len = server_public_key_len; ret = malloc(*auth_data_len); RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, ret, server_public_key, RSA_PKCS1_OAEP_PADDING); } } DBG_RETURN(ret); }
/* {{{ ps_fetch_time */ static void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char *to; DBG_ENTER("ps_fetch_time"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_TIME; t.neg = (zend_bool) to[0]; t.day = (unsigned long) sint4korr(to+1); t.hour = (unsigned int) to[5]; t.minute = (unsigned int) to[6]; t.second = (unsigned int) to[7]; t.second_part = (length > 8) ? (unsigned long) sint4korr(to+8) : 0; t.year = t.month= 0; if (t.day) { /* Convert days to hours at once */ t.hour += t.day*24; t.day = 0; } (*row) += length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_TIME; } /* QQ : How to make this unicode without copying two times the buffer - Unicode equivalent of spprintf? */ length = spprintf(&to, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second); DBG_INF_FMT("%s", to); #if PHP_MAJOR_VERSION >= 6 if (!as_unicode) { #endif ZVAL_STRINGL(zv, to, length, 1); mnd_efree(to); #if PHP_MAJOR_VERSION >= 6 } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; }
/* {{{ mysqlnd_res_meta::fetch_field */ static const MYSQLND_FIELD * MYSQLND_METHOD(mysqlnd_res_meta, fetch_field)(MYSQLND_RES_METADATA * const meta) { DBG_ENTER("mysqlnd_res_meta::fetch_field"); if (meta->current_field >= meta->field_count) { DBG_INF("no more fields"); DBG_RETURN(NULL); } DBG_INF_FMT("name=%s max_length=%u", meta->fields[meta->current_field].name? meta->fields[meta->current_field].name:"", meta->fields[meta->current_field].max_length); DBG_RETURN(&meta->fields[meta->current_field++]); }
/* {{{ ps_fetch_float */ static void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { float value; DBG_ENTER("ps_fetch_float"); float4get(value, *row); ZVAL_DOUBLE(zv, value); (*row)+= 4; DBG_INF_FMT("value=%f", value); DBG_VOID_RETURN; }
/* {{{ mysqlnd_net::encode */ static enum_func_status MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compress_buffer, size_t * compress_buffer_len, const zend_uchar * const uncompressed_data, const size_t uncompressed_data_len) { #ifdef MYSQLND_COMPRESSION_ENABLED int error; uLongf tmp_complen = *compress_buffer_len; DBG_ENTER("mysqlnd_net::encode"); error = compress(compress_buffer, &tmp_complen, uncompressed_data, uncompressed_data_len); if (error != Z_OK) { DBG_INF_FMT("compression NOT successful. error=%d Z_OK=%d Z_BUF_ERROR=%d Z_MEM_ERROR=%d", error, Z_OK, Z_BUF_ERROR, Z_MEM_ERROR); } else { *compress_buffer_len = tmp_complen; DBG_INF_FMT("compression successful. compressed size=%lu", tmp_complen); } DBG_RETURN(error == Z_OK? PASS:FAIL); #else DBG_ENTER("mysqlnd_net::encode"); DBG_RETURN(FAIL); #endif }
/* {{{ ps_fetch_datetime */ static void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_datetime"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_DATETIME; t.neg = 0; t.year = (unsigned int) sint2korr(to); t.month = (unsigned int) to[2]; t.day = (unsigned int) to[3]; if (length > 4) { t.hour = (unsigned int) to[4]; t.minute = (unsigned int) to[5]; t.second = (unsigned int) to[6]; } else { t.hour = t.minute = t.second= 0; } t.second_part = (length > 7) ? (unsigned long) sint4korr(to+7) : 0; (*row)+= length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_DATETIME; } length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); #if MYSQLND_UNICODE if (!as_unicode) { #endif ZVAL_STRINGL(zv, value, length, 1); mnd_sprintf_free(value); #if MYSQLND_UNICODE } else { ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; }
/* {{{ ps_fetch_time */ static void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC) { struct st_mysqlnd_time t; unsigned int length; /* First byte encodes the length*/ char * value; DBG_ENTER("ps_fetch_time"); if ((length = php_mysqlnd_net_field_length(row))) { zend_uchar *to= *row; t.time_type = MYSQLND_TIMESTAMP_TIME; t.neg = (zend_bool) to[0]; t.day = (unsigned long) sint4korr(to+1); t.hour = (unsigned int) to[5]; t.minute = (unsigned int) to[6]; t.second = (unsigned int) to[7]; t.second_part = (length > 8) ? (unsigned long) sint4korr(to+8) : 0; t.year = t.month= 0; if (t.day) { /* Convert days to hours at once */ t.hour += t.day*24; t.day = 0; } (*row) += length; } else { memset(&t, 0, sizeof(t)); t.time_type = MYSQLND_TIMESTAMP_TIME; } length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second); DBG_INF_FMT("%s", value); #if MYSQLND_UNICODE if (!as_unicode) { #endif ZVAL_STRINGL(zv, value, length, 1); mnd_sprintf_free(value); #if MYSQLND_UNICODE } else { ZVAL_UTF8_STRINGL(zv, value, length, ZSTR_AUTOFREE); } #endif DBG_VOID_RETURN; }