Skip to content

Commit 9d91274

Browse files
committed
MB-30278: Subdoc regression tests for backtick un-escaping issue
Regression tests for how KV-Engine subdoc API uses subjson to parse backticked escaped paths. Change-Id: I42a144ba3f37c38d3e4ca0f8990652cda85011c2 Reviewed-on: http://review.couchbase.org/96259 Well-Formed: Build Bot <[email protected]> Reviewed-by: Tim Bradgate <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 2b37a5a commit 9d91274

File tree

4 files changed

+65
-7
lines changed

4 files changed

+65
-7
lines changed

tests/testapp/testapp.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -944,18 +944,18 @@ void validate_object(const char *key, const std::string& expected_value) {
944944
safe_send(send.bytes, len, false);
945945

946946
std::vector<char> receive;
947-
receive.resize(sizeof(protocol_binary_response_get) + expected_value.size());
948-
949-
safe_recv_packet(receive.data(), receive.size());
947+
safe_recv_packet(receive);
950948

951949
auto* response = reinterpret_cast<protocol_binary_response_no_extras*>(receive.data());
952950
mcbp_validate_response_header(response, PROTOCOL_BINARY_CMD_GET,
953951
PROTOCOL_BINARY_RESPONSE_SUCCESS);
954952
char* ptr = receive.data() + sizeof(*response) + 4;
955-
size_t vallen = response->message.header.response.getBodylen() - 4;
956-
ASSERT_EQ(expected_value.size(), vallen);
957-
std::string actual(ptr, vallen);
958-
EXPECT_EQ(expected_value, actual);
953+
if (response->message.header.response.getStatus() ==
954+
PROTOCOL_BINARY_RESPONSE_SUCCESS) {
955+
size_t vallen = response->message.header.response.getBodylen() - 4;
956+
std::string actual(ptr, vallen);
957+
EXPECT_EQ(expected_value, actual);
958+
}
959959
}
960960

961961
void validate_flags(const char *key, uint32_t expected_flags) {
@@ -1352,6 +1352,10 @@ bool safe_recv_packet(std::vector<uint8_t>& buf) {
13521352
return safe_recv_packetT(buf);
13531353
}
13541354

1355+
bool safe_recv_packet(std::vector<char>& buf) {
1356+
return safe_recv_packetT(buf);
1357+
}
1358+
13551359
// Configues the ewouldblock_engine to use the given mode; value
13561360
// is a mode-specific parameter.
13571361
void TestappTest::ewouldblock_engine_configure(ENGINE_ERROR_CODE err_code,

tests/testapp/testapp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ bool safe_recv(void *buf, size_t len);
434434
*/
435435
bool safe_recv_packet(void *buf, size_t size);
436436
bool safe_recv_packet(std::vector<uint8_t>& buf);
437+
bool safe_recv_packet(std::vector<char>& buf);
437438

438439
/* Whether receiving an EOF during a read is considered an error */
439440
void set_allow_closed_read(bool enabled);

tests/testapp/testapp_subdoc.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,34 @@ TEST_P(SubdocTestappTest, SubdocUTF8ValTest) {
18561856
validate_object("dict", "{ \"key1\": \"Ẇ̴̷̦͔͖͚̝̟̋̽ͪ̾ͤ̈́ͯͮͮ̀͗̌ͭ̾͜h̨̥̞͖̬̠͍͖̘̹͎͌̇̂̃ͯͣ͗̆̌̑ͨ̍̊ͪ̆̾̆̚͟͞ȧ̛̰̞̗̞̬̣̹͎̰̝͍͈̮̖̘̫̤̟͆̈́̒͗ͦ̋̓̌̊̋͝ͅţ͒ͮ͋̋̔̽ͥ̂ͭ̒̉̔̃ͫ̌̆̆҉̹͙̟̩̖̩̹̳̜͚̜̜ ͎̲͕̺̔̿̀͒̈́̏̌ͬͫ͒͂ͩͦ̀͝â̢̡̘̫̮̞̩̰̎ͨ̾ͤ̈́͑̉̈ͧ͆̃ͩ͆̚͡ ̧̢̛̙͔̰̹̲̱͔̤̝͖̥͚͓̲̪̯̟̖̏͒̽ͬ̂ͫͩͭ͋̏͊̽͗͊̀ͭ̋͘c̵̴͐̉̇͂̋ͬ̇̃͊ͨ͗̆̄̊́͏̡̡̫̦̦͉̼̙̜͉̯̮̪̫͍̩̼̘̫̻͍o̸̷͕̭̼̺̤͖͚̯̪̥̘̪̼̝̩̮͕̥̟̐͒̏ͭͦͮ̒ͧ̔̉̅̂͜͢͡o̷̢̡͕̟͓̺͚̟̱̜̻͇̘͍̤͓̲ͣͫ̾͛͗̅̐̏͑͆͌̀͜ͅͅͅl̴̡̙̹͖̈̄̌͒ͣ͒̅̏̕ ͛̐̿͋ͦ͛͌̄ͫ̒ͪ͊̀ͤ̀̿͏̶̡҉҉̤͎͖v̸̵̱͇̲͎̩͚̩͈̙̜̳̞̭̯̩̻̮̪ͯ̋̔͗̃̊ͬͮ̄̃͛̂̒̍͘͘a̦̝͇̙̬̬̰̪͙̗̟͙̝̬͛͂͑ͣ̓͑̏ͤ̑̀̚̚͘l͊̔́͋̋ͫ̈́̿̈̉̀͏̡͍͇̲̙̺̮͠uͬ̄̋̔ͪͧͥ͛ͭ̏̅ͫ͊̚͏̧͈̠̱͇͉̦̫͎͠ę̸͔̯̭̤͕̱͈̖͖̯̭̞͈͖ͨ̑̌̓̈ͮ͂̆̀͟ͅ\" }");
18571857
}
18581858

1859+
// MB-30278: Perform a DICT_ADD followed by SD_GET to a path with backticks in
1860+
// them; to verify the path caching of un-escaped components is correctly reset
1861+
// between calls.
1862+
TEST_P(SubdocTestappTest, MB_30278_SubdocBacktickLookup) {
1863+
// Test DICT_ADD where the element key contains a literal backtick.
1864+
store_document("doc", "{}");
1865+
// Add a key with literal backtick (which we escape by passing
1866+
// double-backtick)
1867+
EXPECT_SD_OK(BinprotSubdocCommand(
1868+
PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD, "doc", "key``", "\"value\""));
1869+
EXPECT_SD_GET("doc", "key``", "\"value\"");
1870+
validate_object("doc", R"({"key`":"value"})");
1871+
}
1872+
1873+
// MB-30278: Perform two DICT_ADD calls to paths with backticks in them;
1874+
// to verify the path caching of un-escaped components is correctly reset
1875+
// between calls.
1876+
TEST_P(SubdocTestappTest, MB_30278_SubdocBacktickDictAdd) {
1877+
store_document("doc", "{}");
1878+
EXPECT_SD_OK(BinprotSubdocCommand(
1879+
PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD, "doc", "key``", "\"value\""));
1880+
EXPECT_SD_OK(BinprotSubdocCommand(PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD,
1881+
"doc",
1882+
"key2``",
1883+
"\"value2\""));
1884+
validate_object("doc", R"({"key`":"value","key2`":"value2"})");
1885+
}
1886+
18591887
INSTANTIATE_TEST_CASE_P(
18601888
Subdoc,
18611889
SubdocTestappTest,

tests/testapp/testapp_subdoc_multipath.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,3 +594,28 @@ TEST_P(SubdocTestappTest, SubdocMultiMutation_AddDocFlagInavlidCas) {
594594
"56"});
595595
expect_subdoc_cmd(mutation, PROTOCOL_BINARY_RESPONSE_EINVAL, {});
596596
}
597+
598+
// MB-30278: Perform a multi-mutation with two paths with backticks in them.
599+
TEST_P(SubdocTestappTest, MB_30278_SubdocBacktickMultiMutation) {
600+
store_document("dict", "{}");
601+
602+
SubdocMultiMutationCmd mutation;
603+
mutation.key = "dict";
604+
mutation.specs.push_back({PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD,
605+
SUBDOC_FLAG_NONE,
606+
"key1``",
607+
"1"});
608+
mutation.specs.push_back({PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD,
609+
SUBDOC_FLAG_NONE,
610+
"key2``",
611+
"2"});
612+
mutation.specs.push_back({PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD,
613+
SUBDOC_FLAG_NONE,
614+
"key3``",
615+
"3"});
616+
expect_subdoc_cmd(mutation, PROTOCOL_BINARY_RESPONSE_SUCCESS, {});
617+
618+
validate_object("dict", R"({"key1`":1,"key2`":2,"key3`":3})");
619+
620+
delete_object("dict");
621+
}

0 commit comments

Comments
 (0)