Skip to content

Commit 12c23e4

Browse files
trondndaverigby
authored andcommitted
[subdoc] Add mandatory flags to the command traits
This allows the validators to reject commands which _require_ a given flag to be set for the command (to be used by commands which should only work for XATTRs) Change-Id: I76968b15907cdeffe7952841ee195367d55f217e Reviewed-on: http://review.couchbase.org/c/kv_engine/+/137359 Tested-by: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent 6b5fb6a commit 12c23e4

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

daemon/subdocument_traits.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ SubdocCmdTraits get_subdoc_cmd_traits(cb::mcbp::ClientOpcode cmd) {
8787
Subdoc::Command::INVALID,
8888
cb::mcbp::ClientOpcode::Invalid,
8989
SUBDOC_FLAG_NONE,
90+
SUBDOC_FLAG_NONE,
9091
mcbp::subdoc::doc_flag::None,
9192
false,
9293
false,

daemon/subdocument_traits.h

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct SubdocCmdTraits {
6666
Subdoc::Command subdocCommand;
6767
cb::mcbp::ClientOpcode mcbpCommand;
6868
protocol_binary_subdoc_flag valid_flags : 8;
69+
protocol_binary_subdoc_flag mandatory_flags : 8;
6970
mcbp::subdoc::doc_flag valid_doc_flags;
7071
bool request_has_value;
7172
bool allow_empty_path;
@@ -104,6 +105,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::Get>() {
104105
Subdoc::Command::INVALID,
105106
cb::mcbp::ClientOpcode::Get,
106107
SUBDOC_FLAG_NONE,
108+
SUBDOC_FLAG_NONE,
107109
mcbp::subdoc::doc_flag::AccessDeleted,
108110
/*request_has_value*/ false,
109111
/*allow_empty_path*/ true,
@@ -118,6 +120,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::Set>() {
118120
Subdoc::Command::INVALID,
119121
cb::mcbp::ClientOpcode::Set,
120122
SUBDOC_FLAG_NONE,
123+
SUBDOC_FLAG_NONE,
121124
mcbp::subdoc::doc_flag::Mkdoc | mcbp::subdoc::doc_flag::Add,
122125
/*request_has_value*/ true,
123126
/*allow_empty_path*/ true,
@@ -132,6 +135,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::Delete>() {
132135
Subdoc::Command::INVALID,
133136
cb::mcbp::ClientOpcode::Delete,
134137
SUBDOC_FLAG_NONE,
138+
SUBDOC_FLAG_NONE,
135139
mcbp::subdoc::doc_flag::AccessDeleted,
136140
/*request_has_value*/ false,
137141
/*allow_empty_path*/ true,
@@ -146,6 +150,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocGet>() {
146150
Subdoc::Command::GET,
147151
cb::mcbp::ClientOpcode::Invalid,
148152
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH,
153+
SUBDOC_FLAG_NONE,
149154
mcbp::subdoc::doc_flag::AccessDeleted,
150155
/*request_has_value*/ false,
151156
/*allow_empty_path*/ false,
@@ -160,6 +165,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocExists>() {
160165
Subdoc::Command::EXISTS,
161166
cb::mcbp::ClientOpcode::Invalid,
162167
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH,
168+
SUBDOC_FLAG_NONE,
163169
mcbp::subdoc::doc_flag::AccessDeleted,
164170
/*request_has_value*/ false,
165171
/*allow_empty_path*/ false,
@@ -176,6 +182,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocDictAdd>() {
176182
cb::mcbp::ClientOpcode::Invalid,
177183
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH |
178184
SUBDOC_FLAG_EXPAND_MACROS,
185+
SUBDOC_FLAG_NONE,
179186
doc_flag::Mkdoc | doc_flag::AccessDeleted | doc_flag::Add |
180187
doc_flag::CreateAsDeleted,
181188
/*request_has_value*/ true,
@@ -193,6 +200,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocDictUpsert>() {
193200
cb::mcbp::ClientOpcode::Invalid,
194201
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH |
195202
SUBDOC_FLAG_EXPAND_MACROS,
203+
SUBDOC_FLAG_NONE,
196204
doc_flag::Mkdoc | doc_flag::AccessDeleted | doc_flag::Add |
197205
doc_flag::CreateAsDeleted,
198206
/*request_has_value*/ true,
@@ -208,6 +216,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocDelete>() {
208216
Subdoc::Command::REMOVE,
209217
cb::mcbp::ClientOpcode::Invalid,
210218
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH,
219+
SUBDOC_FLAG_NONE,
211220
mcbp::subdoc::doc_flag::AccessDeleted,
212221
/*request_has_value*/ false,
213222
/*allow_empty_path*/ false,
@@ -223,6 +232,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocReplace>() {
223232
cb::mcbp::ClientOpcode::Invalid,
224233
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH |
225234
SUBDOC_FLAG_EXPAND_MACROS,
235+
SUBDOC_FLAG_NONE,
226236
mcbp::subdoc::doc_flag::AccessDeleted | mcbp::subdoc::doc_flag::Add,
227237
/*request_has_value*/ true,
228238
/*allow_empty_path*/ false,
@@ -235,36 +245,38 @@ template <>
235245
inline SubdocCmdTraits
236246
get_traits<cb::mcbp::ClientOpcode::SubdocArrayPushLast>() {
237247
using namespace mcbp::subdoc;
238-
return SubdocCmdTraits{
239-
CommandScope::SubJSON,
240-
Subdoc::Command::ARRAY_APPEND,
241-
cb::mcbp::ClientOpcode::Invalid,
242-
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH |
243-
SUBDOC_FLAG_EXPAND_MACROS,
244-
doc_flag::Mkdoc | doc_flag::AccessDeleted | doc_flag::Add | doc_flag::CreateAsDeleted,
245-
/*request_has_value*/ true,
246-
/*allow_empty_path*/ true,
247-
ResponseValue::None,
248-
/*is_mutator*/ true,
249-
SubdocPath::SINGLE};
248+
return SubdocCmdTraits{CommandScope::SubJSON,
249+
Subdoc::Command::ARRAY_APPEND,
250+
cb::mcbp::ClientOpcode::Invalid,
251+
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH |
252+
SUBDOC_FLAG_EXPAND_MACROS,
253+
SUBDOC_FLAG_NONE,
254+
doc_flag::Mkdoc | doc_flag::AccessDeleted |
255+
doc_flag::Add | doc_flag::CreateAsDeleted,
256+
/*request_has_value*/ true,
257+
/*allow_empty_path*/ true,
258+
ResponseValue::None,
259+
/*is_mutator*/ true,
260+
SubdocPath::SINGLE};
250261
}
251262

252263
template <>
253264
inline SubdocCmdTraits
254265
get_traits<cb::mcbp::ClientOpcode::SubdocArrayPushFirst>() {
255266
using namespace mcbp::subdoc;
256-
return SubdocCmdTraits{
257-
CommandScope::SubJSON,
258-
Subdoc::Command::ARRAY_PREPEND,
259-
cb::mcbp::ClientOpcode::Invalid,
260-
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH |
261-
SUBDOC_FLAG_EXPAND_MACROS,
262-
doc_flag::Mkdoc | doc_flag::AccessDeleted | doc_flag::Add | doc_flag::CreateAsDeleted,
263-
/*request_has_value*/ true,
264-
/*allow_empty_path*/ true,
265-
ResponseValue::None,
266-
/*is_mutator*/ true,
267-
SubdocPath::SINGLE};
267+
return SubdocCmdTraits{CommandScope::SubJSON,
268+
Subdoc::Command::ARRAY_PREPEND,
269+
cb::mcbp::ClientOpcode::Invalid,
270+
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH |
271+
SUBDOC_FLAG_EXPAND_MACROS,
272+
SUBDOC_FLAG_NONE,
273+
doc_flag::Mkdoc | doc_flag::AccessDeleted |
274+
doc_flag::Add | doc_flag::CreateAsDeleted,
275+
/*request_has_value*/ true,
276+
/*allow_empty_path*/ true,
277+
ResponseValue::None,
278+
/*is_mutator*/ true,
279+
SubdocPath::SINGLE};
268280
}
269281

270282
template <>
@@ -275,6 +287,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocArrayInsert>() {
275287
cb::mcbp::ClientOpcode::Invalid,
276288
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH |
277289
SUBDOC_FLAG_EXPAND_MACROS,
290+
SUBDOC_FLAG_NONE,
278291
doc_flag::AccessDeleted | doc_flag::Add | doc_flag::CreateAsDeleted,
279292
/*request_has_value*/ true,
280293
/*allow_empty_path*/ false,
@@ -291,6 +304,7 @@ get_traits<cb::mcbp::ClientOpcode::SubdocArrayAddUnique>() {
291304
Subdoc::Command::ARRAY_ADD_UNIQUE,
292305
cb::mcbp::ClientOpcode::Invalid,
293306
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH,
307+
SUBDOC_FLAG_NONE,
294308
doc_flag::Mkdoc | doc_flag::AccessDeleted | doc_flag::Add |
295309
doc_flag::CreateAsDeleted,
296310
/*request_has_value*/ true,
@@ -307,6 +321,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocCounter>() {
307321
Subdoc::Command::COUNTER,
308322
cb::mcbp::ClientOpcode::Invalid,
309323
SUBDOC_FLAG_MKDIR_P | SUBDOC_FLAG_XATTR_PATH,
324+
SUBDOC_FLAG_NONE,
310325
doc_flag::Mkdoc | doc_flag::AccessDeleted | doc_flag::Add |
311326
doc_flag::CreateAsDeleted,
312327
/*request_has_value*/ true,
@@ -322,6 +337,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocGetCount>() {
322337
Subdoc::Command::GET_COUNT,
323338
cb::mcbp::ClientOpcode::Invalid,
324339
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH,
340+
SUBDOC_FLAG_NONE,
325341
mcbp::subdoc::doc_flag::AccessDeleted,
326342
/*request_has_value*/ false,
327343
/*allow_empty_path*/ true,
@@ -336,6 +352,7 @@ inline SubdocCmdTraits get_traits<cb::mcbp::ClientOpcode::SubdocMultiLookup>() {
336352
Subdoc::Command::INVALID,
337353
cb::mcbp::ClientOpcode::Invalid,
338354
SUBDOC_FLAG_NONE | SUBDOC_FLAG_XATTR_PATH,
355+
SUBDOC_FLAG_NONE,
339356
mcbp::subdoc::doc_flag::AccessDeleted,
340357
/*request_has_value*/ true,
341358
/*allow_empty_path*/ true,
@@ -351,6 +368,7 @@ get_traits<cb::mcbp::ClientOpcode::SubdocMultiMutation>() {
351368
Subdoc::Command::INVALID,
352369
cb::mcbp::ClientOpcode::Invalid,
353370
SUBDOC_FLAG_NONE,
371+
SUBDOC_FLAG_NONE,
354372
mcbp::subdoc::doc_flag::Mkdoc | mcbp::subdoc::doc_flag::Add,
355373
/*request_has_value*/ true,
356374
/*allow_empty_path*/ true,

daemon/subdocument_validators.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ static cb::mcbp::Status subdoc_validator(Cookie& cookie,
195195
return cb::mcbp::Status::Einval;
196196
}
197197

198+
// Check all mandatory flags are specified
199+
if ((subdoc_flags & traits.mandatory_flags) != traits.mandatory_flags) {
200+
cookie.setErrorContext("Request missing mandatory flags");
201+
return cb::mcbp::Status::Einval;
202+
}
203+
198204
const auto doc_flags = parser.getDocFlag();
199205
if ((doc_flags & ~traits.valid_doc_flags) != mcbp::subdoc::doc_flag::None) {
200206
cookie.setErrorContext("Request document flags invalid");
@@ -403,6 +409,12 @@ static cb::mcbp::Status is_valid_multipath_spec(
403409
return cb::mcbp::Status::Einval;
404410
}
405411

412+
// Check all mandatory flags are specified
413+
if ((flags & op_traits.mandatory_flags) != op_traits.mandatory_flags) {
414+
cookie.setErrorContext("Request missing mandatory flags");
415+
return cb::mcbp::Status::Einval;
416+
}
417+
406418
if ((doc_flags & ~op_traits.valid_doc_flags) !=
407419
mcbp::subdoc::doc_flag::None) {
408420
cookie.setErrorContext("Request document flags invalid");

0 commit comments

Comments
 (0)