summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd_wireprotocol.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2014-06-25 00:42:20 +0800
committerXinchen Hui <laruence@php.net>2014-06-25 00:42:20 +0800
commit8ce23d8f4fc5df0daec05642df8ead016f00fc32 (patch)
tree113281ad36f9f36eb7ad22816d328932a8bfc58a /ext/mysqlnd/mysqlnd_wireprotocol.c
parent284141ca8fa94dac846d593af0628dbfc719402e (diff)
downloadphp-git-8ce23d8f4fc5df0daec05642df8ead016f00fc32.tar.gz
Don't use zend_string for other fields (only name here is enough)
Diffstat (limited to 'ext/mysqlnd/mysqlnd_wireprotocol.c')
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c85
1 files changed, 77 insertions, 8 deletions
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index cf92fa448b..8a5c453a77 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -69,12 +69,12 @@
static const char *unknown_sqlstate= "HY000";
+const char * const mysqlnd_empty_string = "";
/* Used in mysqlnd_debug.c */
const char mysqlnd_read_header_name[] = "mysqlnd_read_header";
const char mysqlnd_read_body_name[] = "mysqlnd_read_body";
-
#define ERROR_MARKER 0xFF
#define EODATA_MARKER 0xFE
@@ -1205,11 +1205,17 @@ void php_mysqlnd_rset_header_free_mem(void * _packet, zend_bool stack_allocation
static size_t rset_field_offsets[] =
{
STRUCT_OFFSET(MYSQLND_FIELD, catalog),
+ STRUCT_OFFSET(MYSQLND_FIELD, catalog_length),
STRUCT_OFFSET(MYSQLND_FIELD, db),
+ STRUCT_OFFSET(MYSQLND_FIELD, db_length),
STRUCT_OFFSET(MYSQLND_FIELD, table),
+ STRUCT_OFFSET(MYSQLND_FIELD, table_length),
STRUCT_OFFSET(MYSQLND_FIELD, org_table),
+ STRUCT_OFFSET(MYSQLND_FIELD, org_table_length),
STRUCT_OFFSET(MYSQLND_FIELD, name),
+ STRUCT_OFFSET(MYSQLND_FIELD, name_length),
STRUCT_OFFSET(MYSQLND_FIELD, org_name),
+ STRUCT_OFFSET(MYSQLND_FIELD, org_name_length),
};
@@ -1223,6 +1229,7 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
zend_uchar *buf = (zend_uchar *) conn->net->cmd_buffer.buffer;
zend_uchar *p = buf;
zend_uchar *begin = buf;
+ char *root_ptr;
unsigned long len;
MYSQLND_FIELD *meta;
unsigned int i, field_count = sizeof(rset_field_offsets)/sizeof(size_t);
@@ -1255,17 +1262,19 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
meta = packet->metadata;
- for (i = 0; i < field_count; i++) {
+ for (i = 0; i < field_count; i += 2) {
len = php_mysqlnd_net_field_length(&p);
BAIL_IF_NO_MORE_DATA;
switch ((len)) {
case 0:
- *(zend_string **)(((char*)meta) + rset_field_offsets[i]) = STR_EMPTY_ALLOC();
+ *(const char **)(((char*)meta) + rset_field_offsets[i]) = mysqlnd_empty_string;
+ *(unsigned int *)(((char*)meta) + rset_field_offsets[i+1]) = 0;
break;
case MYSQLND_NULL_LENGTH:
goto faulty_or_fake;
default:
- *(zend_string **)(((char *)meta) + rset_field_offsets[i]) = STR_INIT((char *)p, len, packet->persistent_alloc);
+ *(const char **)(((char *)meta) + rset_field_offsets[i]) = (const char *)p;
+ *(unsigned int *)(((char*)meta) + rset_field_offsets[i+1]) = len;
p += len;
total_len += len + 1;
break;
@@ -1278,6 +1287,7 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
DBG_ERR_FMT("Protocol error. Server sent false length. Expected 12 got %d", (int) *p);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol error. Server sent false length. Expected 12");
}
+
p++;
BAIL_IF_NO_MORE_DATA;
@@ -1326,14 +1336,73 @@ php_mysqlnd_rset_field_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
{
BAIL_IF_NO_MORE_DATA;
DBG_INF_FMT("Def found, length %lu, persistent=%u", len, packet->persistent_alloc);
- meta->def = STR_INIT((char *)p, len, packet->persistent_alloc);
- p += len;
+ meta->def = mnd_pemalloc(len + 1, packet->persistent_alloc);
+ if (!meta->def) {
+ SET_OOM_ERROR(*conn->error_info);
+ DBG_RETURN(FAIL);
+ }
+ memcpy(meta->def, p, len);
+ meta->def[len] = '\0';
+ meta->def_length = len;
+ p += len;
}
+ root_ptr = meta->root = mnd_pemalloc(total_len, packet->persistent_alloc);
+ if (!root_ptr) {
+ SET_OOM_ERROR(*conn->error_info);
+ DBG_RETURN(FAIL);
+ }
+
+ meta->root_len = total_len;
+
+ if (meta->name != mysqlnd_empty_string) {
+ meta->sname = STR_INIT(meta->name, meta->name_length, packet->persistent_alloc);
+ } else {
+ meta->sname = STR_EMPTY_ALLOC();
+ }
+ meta->name = meta->sname->val;
+ meta->name_length = meta->sname->len;
+
+ /* Now do allocs */
+ if (meta->catalog && meta->catalog != mysqlnd_empty_string) {
+ len = meta->catalog_length;
+ meta->catalog = memcpy(root_ptr, meta->catalog, len);
+ *(root_ptr +=len) = '\0';
+ root_ptr++;
+ }
+
+ if (meta->db && meta->db != mysqlnd_empty_string) {
+ len = meta->db_length;
+ meta->db = memcpy(root_ptr, meta->db, len);
+ *(root_ptr +=len) = '\0';
+ root_ptr++;
+ }
+
+ if (meta->table && meta->table != mysqlnd_empty_string) {
+ len = meta->table_length;
+ meta->table = memcpy(root_ptr, meta->table, len);
+ *(root_ptr +=len) = '\0';
+ root_ptr++;
+ }
+
+ if (meta->org_table && meta->org_table != mysqlnd_empty_string) {
+ len = meta->org_table_length;
+ meta->org_table = memcpy(root_ptr, meta->org_table, len);
+ *(root_ptr +=len) = '\0';
+ root_ptr++;
+ }
+
+ if (meta->org_name && meta->org_name != mysqlnd_empty_string) {
+ len = meta->org_name_length;
+ meta->org_name = memcpy(root_ptr, meta->org_name, len);
+ *(root_ptr +=len) = '\0';
+ root_ptr++;
+ }
+
DBG_INF_FMT("allocing root. persistent=%u", packet->persistent_alloc);
- DBG_INF_FMT("FIELD=[%s.%s.%s]", meta->db? meta->db->val:"*NA*", meta->table? meta->table->val:"*NA*",
- meta->name? meta->name->val:"*NA*");
+ DBG_INF_FMT("FIELD=[%s.%s.%s]", meta->db? meta->db:"*NA*", meta->table? meta->table:"*NA*",
+ meta->name? meta->name:"*NA*");
DBG_RETURN(PASS);