Author: phunt
Date: Thu May 21 21:22:10 2009
New Revision: 777265

URL: http://svn.apache.org/viewvc?rev=777265&view=rev
Log:
ZOOKEEPER-402. zookeeper c library segfaults on data for a node in zookeeper 
being null

Modified:
    hadoop/zookeeper/trunk/CHANGES.txt
    hadoop/zookeeper/trunk/src/c/include/zookeeper.h
    hadoop/zookeeper/trunk/src/c/src/recordio.c
    hadoop/zookeeper/trunk/src/c/src/zookeeper.c
    hadoop/zookeeper/trunk/src/c/tests/TestClient.cc

Modified: hadoop/zookeeper/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/CHANGES.txt?rev=777265&r1=777264&r2=777265&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/CHANGES.txt (original)
+++ hadoop/zookeeper/trunk/CHANGES.txt Thu May 21 21:22:10 2009
@@ -89,6 +89,9 @@
   ZOOKEEPER-411. Building zookeeper fails on RHEL 5 64 bit during test-cppunit
   (mahadev via phunt)
 
+  ZOOKEEPER-402. zookeeper c library segfaults on data for a node in zookeeper
+  being null. (mahadev via phunt)
+
 IMPROVEMENTS:
   ZOOKEEPER-308. improve the atomic broadcast performance 3x.
   (breed via mahadev)

Modified: hadoop/zookeeper/trunk/src/c/include/zookeeper.h
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/include/zookeeper.h?rev=777265&r1=777264&r2=777265&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/include/zookeeper.h (original)
+++ hadoop/zookeeper/trunk/src/c/include/zookeeper.h Thu May 21 21:22:10 2009
@@ -946,7 +946,8 @@
  * \param path The name of the node. Expressed as a file name with slashes 
  * separating ancestors of the node.
  * \param value The data to be stored in the node.
- * \param valuelen The number of bytes in data.
+ * \param valuelen The number of bytes in data. To set the data to be NULL use
+  * value as NULL and valuelen as -1.
  * \param acl The initial ACL of the node. If null, the ACL of the parent will 
be
  *    used.
  * \param flags this parameter can be set to 0 for normal create or an OR
@@ -1047,7 +1048,7 @@
  * the client if the node changes.
  * \param buffer the buffer holding the node data returned by the server
  * \param buffer_len is the size of the buffer pointed to by the buffer 
parameter.
- * It'll be set to the actual data length upon return.
+ * It'll be set to the actual data length upon return. If the data is NULL, 
length is -1.
  * \param stat if not NULL, will hold the value of stat for the path on return.
  * \return return value of the function call.
  * ZOK operation completed succesfully
@@ -1076,7 +1077,7 @@
  * is associated with the given instance of the watcher only.
  * \param buffer the buffer holding the node data returned by the server
  * \param buffer_len is the size of the buffer pointed to by the buffer 
parameter.
- * It'll be set to the actual data length upon return.
+ * It'll be set to the actual data length upon return. If the data is NULL, 
length is -1.
  * \param stat if not NULL, will hold the value of stat for the path on return.
  * \return return value of the function call.
  * ZOK operation completed succesfully
@@ -1098,7 +1099,8 @@
  * \param path the name of the node. Expressed as a file name with slashes 
  * separating ancestors of the node.
  * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write.
+ * \param buflen the number of bytes from buffer to write. To set NULL as data 
+ * use buffer as NULL and buflen as -1.
  * \param version the expected version of the node. The function will fail if 
  * the actual version of the node does not match the expected version. If -1 
is 
  * used the version check will not take place. 
@@ -1123,7 +1125,8 @@
  * \param path the name of the node. Expressed as a file name with slashes 
  * separating ancestors of the node.
  * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write.
+ * \param buflen the number of bytes from buffer to write. To set NULL as data
+ * use buffer as NULL and buflen as -1.
  * \param version the expected version of the node. The function will fail if 
  * the actual version of the node does not match the expected version. If -1 
is 
  * used the version check will not take place. 

Modified: hadoop/zookeeper/trunk/src/c/src/recordio.c
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/src/recordio.c?rev=777265&r1=777264&r2=777265&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/src/recordio.c (original)
+++ hadoop/zookeeper/trunk/src/c/src/recordio.c Thu May 21 21:22:10 2009
@@ -139,6 +139,12 @@
     rc = oa_serialize_int(oa, "len", &b->len);
     if (rc < 0)
         return rc;
+    // this means a buffer of NUll 
+    // with size of -1. This is 
+    // waht we use in java serialization for NULL
+    if (b->len == -1) {
+      return rc;
+    }
     if ((priv->len - priv->off) < b->len) {
         rc = resize_buffer(priv, priv->len + b->len);
         if (rc < 0)
@@ -234,6 +240,11 @@
     if ((priv->len - priv->off) < b->len) {
         return -E2BIG;
     }
+    // set the buffer to null
+    if (b->len == -1) {
+       b->buff = NULL;
+       return rc;
+    }
     b->buff = malloc(b->len);
     if (!b->buff) {
         return -ENOMEM;

Modified: hadoop/zookeeper/trunk/src/c/src/zookeeper.c
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/src/zookeeper.c?rev=777265&r1=777264&r2=777265&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/src/zookeeper.c (original)
+++ hadoop/zookeeper/trunk/src/c/src/zookeeper.c Thu May 21 21:22:10 2009
@@ -1629,7 +1629,13 @@
                             len = sc->u.data.buff_len;
                         }
                         sc->u.data.buff_len = len;
-                        memcpy(sc->u.data.buffer, res.data.buff, len);
+                        // check if len is negative 
+                        // just of NULL which is -1 int 
+                        if (len == -1) {
+                            sc->u.data.buffer = NULL;
+                        } else {
+                            memcpy(sc->u.data.buffer, res.data.buff, len);
+                        }
                         sc->u.data.stat = res.stat;
                         deallocate_GetDataResponse(&res);
                     }

Modified: hadoop/zookeeper/trunk/src/c/tests/TestClient.cc
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/tests/TestClient.cc?rev=777265&r1=777264&r2=777265&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/src/c/tests/TestClient.cc (original)
+++ hadoop/zookeeper/trunk/src/c/tests/TestClient.cc Thu May 21 21:22:10 2009
@@ -157,6 +157,7 @@
     CPPUNIT_TEST_SUITE(Zookeeper_simpleSystem);
     CPPUNIT_TEST(testAsyncWatcherAutoReset);
 #ifdef THREADED
+    CPPUNIT_TEST(testNullData);
     CPPUNIT_TEST(testPathValidation);
     CPPUNIT_TEST(testPing);
     CPPUNIT_TEST(testAcl);
@@ -402,6 +403,26 @@
         CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
     }
 
+    void testNullData() {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        CPPUNIT_ASSERT(zk);
+        int rc = 0;
+        rc = zoo_create(zk, "/mahadev", NULL, -1, 
+                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        char buffer[512];
+        struct Stat stat;
+        int len = 512;
+        rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
+        CPPUNIT_ASSERT_EQUAL( -1, len);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_set(zk, "/mahadev", NULL, -1, -1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
+        CPPUNIT_ASSERT_EQUAL( -1, len);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+    }
 
     void testPathValidation() {
         watchctx_t ctx;


Reply via email to