You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by bo...@apache.org on 2009/02/21 22:40:36 UTC

svn commit: r746593 - in /apr/apr-util/branches/1.4.x: CHANGES memcache/apr_memcache.c

Author: bojan
Date: Sat Feb 21 21:40:35 2009
New Revision: 746593

URL: http://svn.apache.org/viewvc?rev=746593&view=rev
Log:
Backport r746592 from the trunk.
Fix apr_memcache_multgetp memory corruption and incorrect error handling.
Patch by Sami Tolvanen <sami.tolvanen mywot.com>.
PR 46588.

Modified:
    apr/apr-util/branches/1.4.x/CHANGES
    apr/apr-util/branches/1.4.x/memcache/apr_memcache.c

Modified: apr/apr-util/branches/1.4.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/CHANGES?rev=746593&r1=746592&r2=746593&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/CHANGES [utf-8] (original)
+++ apr/apr-util/branches/1.4.x/CHANGES [utf-8] Sat Feb 21 21:40:35 2009
@@ -1,6 +1,9 @@
                                                      -*- coding: utf-8 -*-
 Changes with APR-util 1.4.0
 
+  *) Fix apr_memcache_multgetp memory corruption and incorrect error
+     handling. PR 46588 [Sami Tolvanen <sami.tolvanen mywot.com>]
+
   *) Fix memcache memory leak with persistent connections.
      PR 46482 [Sami Tolvanen <sami.tolvanen mywot.com>]
 

Modified: apr/apr-util/branches/1.4.x/memcache/apr_memcache.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.4.x/memcache/apr_memcache.c?rev=746593&r1=746592&r2=746593&view=diff
==============================================================================
--- apr/apr-util/branches/1.4.x/memcache/apr_memcache.c (original)
+++ apr/apr-util/branches/1.4.x/memcache/apr_memcache.c Sat Feb 21 21:40:35 2009
@@ -1128,7 +1128,8 @@
     apr_hash_set(*values, value->key, klen, value);
 }
 
-static void mget_conn_result(int up,
+static void mget_conn_result(int serverup,
+                             int connup,
                              apr_status_t rv,
                              apr_memcache_t *mc,
                              apr_memcache_server_t *ms,
@@ -1140,9 +1141,16 @@
     apr_int32_t j;
     apr_memcache_value_t* value;
     
-    if (!up) {
+    apr_hash_set(server_queries, &ms, sizeof(ms), NULL);
+
+    if (connup) {
+        ms_release_conn(ms, conn);
+    } else {
         ms_bad_conn(ms, conn);
-        apr_memcache_disable_server(mc, ms);
+
+        if (!serverup) {
+            apr_memcache_disable_server(mc, ms);
+        }
     }
     
     for (j = 1; j < server_query->query_vec_count ; j+=2) {
@@ -1155,10 +1163,6 @@
             }
         }
     }
-
-    ms_release_conn(ms, conn);
-    
-    apr_hash_set(server_queries, &ms, sizeof(ms), NULL);
 }
 
 APU_DECLARE(apr_status_t)
@@ -1265,6 +1269,18 @@
     rv = apr_pollset_create(&pollset, apr_hash_count(server_queries), temp_pool, 0);
 
     if (rv != APR_SUCCESS) {
+        query_hash_index = apr_hash_first(temp_pool, server_queries);
+
+        while (query_hash_index) {
+            void *v;
+            apr_hash_this(query_hash_index, NULL, NULL, &v);
+            server_query = v;
+            query_hash_index = apr_hash_next(query_hash_index);
+
+            mget_conn_result(TRUE, TRUE, rv, mc, server_query->ms, server_query->conn,
+                             server_query, values, server_queries);
+        }
+
         return rv;
     }
 
@@ -1287,7 +1303,7 @@
         }
 
         if (rv != APR_SUCCESS) {
-            mget_conn_result(FALSE, rv, mc, ms, conn,
+            mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                              server_query, values, server_queries);
             continue;
         }
@@ -1319,7 +1335,7 @@
 
            if (rv != APR_SUCCESS) {
                apr_pollset_remove (pollset, &activefds[i]);
-               mget_conn_result(FALSE, rv, mc, ms, conn,
+               mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                 server_query, values, server_queries);
                queries_sent--;
                continue;
@@ -1349,7 +1365,7 @@
 
                
                if (value) {
-                   if (len > 0)  {
+                   if (len >= 0)  {
                        apr_bucket_brigade *bbb;
                        apr_bucket *e;
                        
@@ -1358,7 +1374,7 @@
                        
                        if (rv != APR_SUCCESS) {
                            apr_pollset_remove (pollset, &activefds[i]);
-                           mget_conn_result(FALSE, rv, mc, ms, conn,
+                           mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                             server_query, values, server_queries);
                            queries_sent--;
                            continue;
@@ -1370,7 +1386,7 @@
                        
                        if (rv != APR_SUCCESS) {
                            apr_pollset_remove (pollset, &activefds[i]);
-                           mget_conn_result(FALSE, rv, mc, ms, conn,
+                           mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                             server_query, values, server_queries);
                            queries_sent--;
                            continue;
@@ -1379,7 +1395,7 @@
                        rv = apr_brigade_destroy(conn->bb);
                        if (rv != APR_SUCCESS) {
                            apr_pollset_remove (pollset, &activefds[i]);
-                           mget_conn_result(FALSE, rv, mc, ms, conn,
+                           mget_conn_result(FALSE, FALSE, rv, mc, ms, conn,
                                             server_query, values, server_queries);
                            queries_sent--;
                            continue;
@@ -1430,13 +1446,13 @@
         conn = server_query->conn;
         ms = server_query->ms;
         
-        mget_conn_result(TRUE, rv, mc, ms, conn,
+        mget_conn_result(TRUE, (rv == APR_SUCCESS), rv, mc, ms, conn,
                          server_query, values, server_queries);
         continue;
     }
     
-    apr_pool_clear(temp_pool);
     apr_pollset_destroy(pollset);
+    apr_pool_clear(temp_pool);
     return APR_SUCCESS;
     
 }