MB-23112 Fix deleteWithMeta and extended meta data input 29/74529/4
authorJim Walker <jim@couchbase.com>
Thu, 2 Mar 2017 16:28:35 +0000 (16:28 +0000)
committerDave Finlay <dave.finlay@couchbase.com>
Thu, 2 Mar 2017 20:03:02 +0000 (20:03 +0000)
An incorrect offset meant that we tried to parse an incorrect
part of the packet as ExtendedMetaData.

Test code updated to cover this case.

Change-Id: If0610fe73b378e5830b4f4b9978d2b7507b516b4
Reviewed-on: http://review.couchbase.org/74529
Reviewed-by: David Haikney <david.haikney@couchbase.com>
Tested-by: Build Bot <build@couchbase.com>
Reviewed-by: Dave Rigby <daver@couchbase.com>
Well-Formed: Build Bot <build@couchbase.com>

src/ep_engine.cc
tests/ep_testsuite_xdcr.cc

index 064c237..306aa2d 100644 (file)
@@ -5707,6 +5707,7 @@ ENGINE_ERROR_CODE EventuallyPersistentEngine::deleteWithMeta(
         if (nmeta > 0) {
             try {
                 emd.reset(new ExtendedMetaData(request->bytes +
+                                               sizeof(request->bytes) +
                                                nkey +
                                                keyOffset, nmeta));
             } catch (const std::bad_alloc&) {
index cc3702a..90123da 100644 (file)
@@ -1898,16 +1898,23 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
     // Watson (4.6) accepts valid encodings, but ignores them
     std::vector<char> junkMeta = {-2,-1,2,3};
 
+    int force = 0;
+
+    if (strstr(testHarness.get_current_testcase()->cfg,
+               "conflict_resolution_type=lww") != nullptr) {
+        force = FORCE_ACCEPT_WITH_META_OPS;
+    }
+
     // Set the key and junk nmeta
     set_with_meta(h, h1, "key", 3, NULL, 0, 0, &itemMeta, 0,
-                  FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                  force, PROTOCOL_BINARY_RAW_BYTES,
                   nullptr, junkMeta);
     checkeq(PROTOCOL_BINARY_RESPONSE_EINVAL, last_status.load(), "Expected EINVAL");
 
     // Set the key and junk nmeta that's quite large
     junkMeta.resize(std::numeric_limits<uint16_t>::max());
     set_with_meta(h, h1, "key", 3, NULL, 0, 0, &itemMeta, 0,
-                  FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                  force, PROTOCOL_BINARY_RAW_BYTES,
                   nullptr, junkMeta);
     checkeq(PROTOCOL_BINARY_RESPONSE_EINVAL, last_status.load(), "Expected EINVAL");
 
@@ -1955,14 +1962,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key1", 4, nullptr, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key1", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -1977,14 +1984,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key2", 4, nullptr, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key2", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -2001,14 +2008,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key3", 4, nullptr, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key3", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -2025,14 +2032,14 @@ static enum test_result test_cas_options_and_nmeta(ENGINE_HANDLE *h,
 
         // Set the key with a low CAS value and real nmeta
         set_with_meta(h, h1, "key4", 4, NULL, 0, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, PROTOCOL_BINARY_RAW_BYTES,
+                      force, PROTOCOL_BINARY_RAW_BYTES,
                       nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
 
         itemMeta.cas++;
         del_with_meta(h, h1, "key4", 4, 0, &itemMeta, 0,
-                      FORCE_ACCEPT_WITH_META_OPS, nullptr, validMetaVector);
+                      force, nullptr, validMetaVector);
         checkeq(PROTOCOL_BINARY_RESPONSE_SUCCESS, last_status.load(),
                 "Expected success");
     }
@@ -2143,10 +2150,14 @@ BaseTestCase testsuite_testcases[] = {
                  test_cas_regeneration, test_setup, teardown,
                  "conflict_resolution_type=seqno",
                  prepare, cleanup),
-        TestCase("test CAS options and nmeta",
+        TestCase("test CAS options and nmeta (lww)",
                  test_cas_options_and_nmeta, test_setup, teardown,
                  "conflict_resolution_type=lww",
                  prepare, cleanup),
+        TestCase("test CAS options and nmeta (seqno)",
+                 test_cas_options_and_nmeta, test_setup, teardown,
+                 "conflict_resolution_type=seqno",
+                 prepare, cleanup),
 
         TestCase(NULL, NULL, NULL, NULL, NULL, prepare, cleanup)
 };