]> granicus.if.org Git - php/commitdiff
OOM stability fixes
authorAndrey Hristov <andrey@php.net>
Tue, 4 May 2010 14:02:42 +0000 (14:02 +0000)
committerAndrey Hristov <andrey@php.net>
Tue, 4 May 2010 14:02:42 +0000 (14:02 +0000)
ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_wireprotocol.c

index d8b37b01ee0c66a60d08ee6897c0853548d99d02..778663b08ab8bec2773c77513eabd065cce60324 100644 (file)
@@ -1227,19 +1227,25 @@ MYSQLND_METHOD(mysqlnd_stmt, send_long_data)(MYSQLND_STMT * const s, unsigned in
 
        if (CONN_GET_STATE(conn) == CONN_READY) {
                size_t packet_len;
-               stmt->param_bind[param_no].flags |= MYSQLND_PARAM_BIND_BLOB_USED;
                cmd_buf = mnd_emalloc(packet_len = STMT_ID_LENGTH + 2 + length);
-
-               int4store(cmd_buf, stmt->stmt_id);
-               int2store(cmd_buf + STMT_ID_LENGTH, param_no);
-               memcpy(cmd_buf + STMT_ID_LENGTH + 2, data, length);
-
-               /* COM_STMT_SEND_LONG_DATA doesn't send an OK packet*/
-               ret = conn->m->simple_command(conn, cmd, (char *)cmd_buf, packet_len,
-                                                                        PROT_LAST , FALSE, TRUE TSRMLS_CC);
-               mnd_efree(cmd_buf);
-               if (FAIL == ret) {
-                       stmt->error_info = conn->error_info;
+               if (cmd_buf) {
+                       stmt->param_bind[param_no].flags |= MYSQLND_PARAM_BIND_BLOB_USED;
+
+                       int4store(cmd_buf, stmt->stmt_id);
+                       int2store(cmd_buf + STMT_ID_LENGTH, param_no);
+                       memcpy(cmd_buf + STMT_ID_LENGTH + 2, data, length);
+
+                       /* COM_STMT_SEND_LONG_DATA doesn't send an OK packet*/
+                       ret = conn->m->simple_command(conn, cmd, (char *)cmd_buf, packet_len,
+                                                                                PROT_LAST , FALSE, TRUE TSRMLS_CC);
+                       mnd_efree(cmd_buf);
+                       if (FAIL == ret) {
+                               stmt->error_info = conn->error_info;
+                       }
+               } else {
+                       ret = FAIL;
+                       SET_OOM_ERROR(stmt->error_info);                        
+                       SET_OOM_ERROR(conn->error_info);                        
                }
                /*
                  Cover protocol error: COM_STMT_SEND_LONG_DATA was designed to be quick and not
index 26e05ac7f77addb6c8b525adb97695a34d74bf65..02380457f84c886da2ddd37f8865090373f3d808 100644 (file)
@@ -359,9 +359,16 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT * s TSRMLS_DC)
        DBG_INF_FMT("stmt=%d", stmt? stmt->stmt_id:0);
 
        ret = FAIL;
-       rset_header = conn->protocol->m.get_rset_header_packet(conn->protocol, FALSE TSRMLS_CC);
        do {
+               rset_header = conn->protocol->m.get_rset_header_packet(conn->protocol, FALSE TSRMLS_CC);
+               if (!rset_header) {
+                       SET_OOM_ERROR(conn->error_info);
+                       ret = FAIL;
+                       break;          
+               }
+
                SET_ERROR_AFF_ROWS(conn);
+
                if (FAIL == (ret = PACKET_READ(rset_header, conn))) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error reading result set's header");
                        break;
index 75391d390a1cdfe9eb9d174bef6816289bd1702c..39a3c94b043977579380601c7934123942ba064e 100644 (file)
@@ -777,6 +777,7 @@ void php_mysqlnd_cmd_free_mem(void *_packet, zend_bool alloca TSRMLS_DC)
 static enum_func_status
 php_mysqlnd_rset_header_read(void *_packet, MYSQLND *conn TSRMLS_DC)
 {
+       enum_func_status ret = PASS;
        size_t buf_len = conn->net->cmd_buffer.length;
        zend_uchar *buf = (zend_uchar *) conn->net->cmd_buffer.buffer;
        zend_uchar *p = buf;
@@ -819,9 +820,14 @@ php_mysqlnd_rset_header_read(void *_packet, MYSQLND *conn TSRMLS_DC)
                        */
                        len = packet->header.size - 1;
                        packet->info_or_local_file = mnd_emalloc(len + 1);
-                       memcpy(packet->info_or_local_file, p, len);
-                       packet->info_or_local_file[len] = '\0';
-                       packet->info_or_local_file_len = len;
+                       if (packet->info_or_local_file) {
+                               memcpy(packet->info_or_local_file, p, len);
+                               packet->info_or_local_file[len] = '\0';
+                               packet->info_or_local_file_len = len;
+                       } else {
+                               SET_OOM_ERROR(conn->error_info);
+                               ret = FAIL;     
+                       }
                        break;
                case 0x00:
                        DBG_INF("UPSERT");
@@ -841,9 +847,14 @@ php_mysqlnd_rset_header_read(void *_packet, MYSQLND *conn TSRMLS_DC)
                        /* Check for additional textual data */
                        if (packet->header.size  > (size_t) (p - buf) && (len = php_mysqlnd_net_field_length(&p))) {
                                packet->info_or_local_file = mnd_emalloc(len + 1);
-                               memcpy(packet->info_or_local_file, p, len);
-                               packet->info_or_local_file[len] = '\0';
-                               packet->info_or_local_file_len = len;
+                               if (packet->info_or_local_file) {
+                                       memcpy(packet->info_or_local_file, p, len);
+                                       packet->info_or_local_file[len] = '\0';
+                                       packet->info_or_local_file_len = len;
+                               } else {
+                                       SET_OOM_ERROR(conn->error_info);
+                                       ret = FAIL;
+                               }
                        }
                        DBG_INF_FMT("affected_rows=%llu last_insert_id=%llu server_status=%d warning_count=%d",
                                                packet->affected_rows, packet->last_insert_id,
@@ -856,7 +867,7 @@ php_mysqlnd_rset_header_read(void *_packet, MYSQLND *conn TSRMLS_DC)
        }
        BAIL_IF_NO_MORE_DATA;
 
-       DBG_RETURN(PASS);
+       DBG_RETURN(ret);
 premature_end:
        DBG_ERR_FMT("RSET_HEADER packet %d bytes shorter than expected", p - begin - packet->header.size);
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "RSET_HEADER packet "MYSQLND_SZ_T_SPEC" bytes shorter than expected",