@@ -1613,16 +1613,13 @@ TEST_F(SingleThreadedEPBucketTest, MB_29861) {
16131613 /* startseq*/ 0 ,
16141614 /* endseq*/ 2 ,
16151615 /* flags*/ MARKER_FLAG_DISK);
1616- std::string data = R"( {"json":"yes"})" ;
1617- cb::const_byte_buffer value{reinterpret_cast <const uint8_t *>(data.data ()),
1618- data.size ()};
16191616
16201617 // 2. Now add a deletion.
16211618 consumer->deletion (/* opaque*/ 1 ,
16221619 {" key1" , DocNamespace::DefaultCollection},
1623- /* values */ value ,
1620+ /* value */ {} ,
16241621 /* priv_bytes*/ 0 ,
1625- /* datatype*/ PROTOCOL_BINARY_DATATYPE_JSON ,
1622+ /* datatype*/ PROTOCOL_BINARY_RAW_BYTES ,
16261623 /* cas*/ 0 ,
16271624 /* vbucket*/ vbid,
16281625 /* bySeqno*/ 1 ,
@@ -1659,7 +1656,7 @@ TEST_F(SingleThreadedEPBucketTest, MB_29861) {
16591656 deleted,
16601657 datatype));
16611658 EXPECT_EQ (1 , deleted);
1662- EXPECT_EQ (PROTOCOL_BINARY_DATATYPE_JSON , datatype);
1659+ EXPECT_EQ (PROTOCOL_BINARY_RAW_BYTES , datatype);
16631660 EXPECT_NE (0 , metadata.exptime ); // A locally created deleteTime
16641661}
16651662
@@ -1684,15 +1681,12 @@ TEST_F(SingleThreadedEPBucketTest, MB_27457) {
16841681 /* startseq*/ 0 ,
16851682 /* endseq*/ 2 ,
16861683 /* flags*/ 0 );
1687- std::string data = R"( {"json":"yes"})" ;
1688- cb::const_byte_buffer value{reinterpret_cast <const uint8_t *>(data.data ()),
1689- data.size ()};
16901684 // 2. Now add two deletions, one without deleteTime, one with
16911685 consumer->deletionV2 (/* opaque*/ 1 ,
16921686 {" key1" , DocNamespace::DefaultCollection},
1693- /* values*/ value ,
1687+ /* values*/ {} ,
16941688 /* priv_bytes*/ 0 ,
1695- /* datatype*/ PROTOCOL_BINARY_DATATYPE_JSON ,
1689+ /* datatype*/ PROTOCOL_BINARY_RAW_BYTES ,
16961690 /* cas*/ 0 ,
16971691 /* vbucket*/ vbid,
16981692 /* bySeqno*/ 1 ,
@@ -1702,9 +1696,9 @@ TEST_F(SingleThreadedEPBucketTest, MB_27457) {
17021696 const uint32_t deleteTime = 10 ;
17031697 consumer->deletionV2 (/* opaque*/ 1 ,
17041698 {" key2" , DocNamespace::DefaultCollection},
1705- /* values */ value ,
1699+ /* value */ {} ,
17061700 /* priv_bytes*/ 0 ,
1707- /* datatype*/ PROTOCOL_BINARY_DATATYPE_JSON ,
1701+ /* datatype*/ PROTOCOL_BINARY_RAW_BYTES ,
17081702 /* cas*/ 0 ,
17091703 /* vbucket*/ vbid,
17101704 /* bySeqno*/ 2 ,
@@ -1741,7 +1735,7 @@ TEST_F(SingleThreadedEPBucketTest, MB_27457) {
17411735 deleted,
17421736 datatype));
17431737 EXPECT_EQ (1 , deleted);
1744- EXPECT_EQ (PROTOCOL_BINARY_DATATYPE_JSON , datatype);
1738+ EXPECT_EQ (PROTOCOL_BINARY_RAW_BYTES , datatype);
17451739 EXPECT_NE (0 , metadata.exptime ); // A locally created deleteTime
17461740
17471741 deleted = 0 ;
@@ -1762,7 +1756,7 @@ TEST_F(SingleThreadedEPBucketTest, MB_27457) {
17621756 deleted,
17631757 datatype));
17641758 EXPECT_EQ (1 , deleted);
1765- EXPECT_EQ (PROTOCOL_BINARY_DATATYPE_JSON , datatype);
1759+ EXPECT_EQ (PROTOCOL_BINARY_RAW_BYTES , datatype);
17661760 EXPECT_EQ (deleteTime, metadata.exptime ); // Our replicated deleteTime!
17671761}
17681762
@@ -3037,6 +3031,69 @@ TEST_P(XattrCompressedTest, MB_29040_sanitise_input) {
30373031 gv.item ->getDataType ());
30383032}
30393033
3034+ // Create a replica VB and consumer, then send it an delete with value which
3035+ // should never of been created on the source.
3036+ TEST_F (SingleThreadedEPBucketTest, MB_31141_sanitise_input) {
3037+ setVBucketStateAndRunPersistTask (vbid, vbucket_state_replica);
3038+
3039+ auto consumer = std::make_shared<MockDcpConsumer>(
3040+ *engine, cookie, " MB_31141_sanitise_input" );
3041+ int opaque = 1 ;
3042+ ASSERT_EQ (ENGINE_SUCCESS, consumer->addStream (opaque, vbid, /* flags*/ 0 ));
3043+
3044+ std::string body = " value" ;
3045+
3046+ // Send deletion in a single seqno snapshot
3047+ int64_t bySeqno = 1 ;
3048+ EXPECT_EQ (ENGINE_SUCCESS,
3049+ consumer->snapshotMarker (
3050+ opaque, vbid, bySeqno, bySeqno, MARKER_FLAG_CHK));
3051+
3052+ EXPECT_EQ (ENGINE_SUCCESS,
3053+ consumer->deletion (opaque,
3054+ {" key" , DocNamespace::DefaultCollection},
3055+ {reinterpret_cast <const uint8_t *>(body.data ()),
3056+ body.size ()},
3057+ /* priv_bytes*/ 0 ,
3058+ PROTOCOL_BINARY_DATATYPE_SNAPPY |
3059+ PROTOCOL_BINARY_RAW_BYTES,
3060+ /* cas*/ 3 ,
3061+ vbid,
3062+ bySeqno,
3063+ /* revSeqno*/ 0 ,
3064+ /* meta*/ {}));
3065+
3066+ EXPECT_EQ (std::make_pair (false , size_t (1 )),
3067+ getEPBucket ().flushVBucket (vbid));
3068+
3069+ ASSERT_EQ (ENGINE_SUCCESS, consumer->closeStream (opaque, vbid));
3070+
3071+ // Switch to active
3072+ setVBucketStateAndRunPersistTask (vbid, vbucket_state_active);
3073+
3074+ get_options_t options = static_cast <get_options_t >(
3075+ QUEUE_BG_FETCH | HONOR_STATES | TRACK_REFERENCE | DELETE_TEMP |
3076+ HIDE_LOCKED_CAS | TRACK_STATISTICS | GET_DELETED_VALUE);
3077+ auto gv = store->get (
3078+ {" key" , DocNamespace::DefaultCollection}, vbid, cookie, options);
3079+ EXPECT_EQ (ENGINE_EWOULDBLOCK, gv.getStatus ());
3080+
3081+ // Manually run the bgfetch task.
3082+ MockGlobalTask mockTask (engine->getTaskable (), TaskId::MultiBGFetcherTask);
3083+ store->getVBucket (vbid)->getShard ()->getBgFetcher ()->run (&mockTask);
3084+ gv = store->get ({" key" , DocNamespace::DefaultCollection},
3085+ vbid,
3086+ cookie,
3087+ GET_DELETED_VALUE);
3088+ ASSERT_EQ (ENGINE_SUCCESS, gv.getStatus ());
3089+
3090+ EXPECT_TRUE (gv.item ->isDeleted ());
3091+ EXPECT_EQ (0 , gv.item ->getFlags ());
3092+ EXPECT_EQ (3 , gv.item ->getCas ());
3093+ EXPECT_EQ (0 , gv.item ->getValue ()->valueSize ());
3094+ EXPECT_EQ (PROTOCOL_BINARY_RAW_BYTES, gv.item ->getDataType ());
3095+ }
3096+
30403097// Test highlighting MB_29480 - this is not demonstrating the issue is fixed.
30413098TEST_F (SingleThreadedEPBucketTest, MB_29480) {
30423099 // Make vbucket active.
0 commit comments