Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: vdavydov.dev@gmail.com
Subject: [PATCH 3/8] Add 'exact_field_count' parameter to options decoder
Date: Wed,  8 Aug 2018 01:03:46 +0300	[thread overview]
Message-ID: <eb2fd1e6f6c7bc44310014ce6277bb926e7e0fe2.1533679264.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1533679264.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1533679264.git.v.shpilevoy@tarantool.org>

Needed for promotion. Promotion uses system space
_promotion, into which a user can write tuples directly
with not API usage (and we can not do anything with it),
so _promotion should do severe validation of each field
of each tuple since it affects the cluster state.

For this a new parameter of options decoder is introduced,
that checks for exact field count.

Needed for #3055
---
 src/box/alter.cc  | 10 +++++-----
 src/box/key_def.c |  2 +-
 src/box/opt_def.c | 13 ++++++++-----
 src/box/opt_def.h | 16 +++++++++++++++-
 4 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index 3007a131d..d13ecb783 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -239,7 +239,7 @@ index_opts_decode(struct index_opts *opts, const char *map)
 {
 	index_opts_create(opts);
 	if (opts_decode(opts, index_opts_reg, &map, ER_WRONG_INDEX_OPTIONS,
-			BOX_INDEX_FIELD_OPTS, NULL) != 0)
+			BOX_INDEX_FIELD_OPTS, NULL, 0) != 0)
 		diag_raise();
 	if (opts->distance == rtree_index_distance_type_MAX) {
 		tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
@@ -403,8 +403,8 @@ space_opts_decode(struct space_opts *opts, const char *data)
 				flags++;
 		}
 	} else if (opts_decode(opts, space_opts_reg, &data,
-			       ER_WRONG_SPACE_OPTIONS,
-			       BOX_SPACE_FIELD_OPTS, NULL) != 0) {
+			       ER_WRONG_SPACE_OPTIONS, BOX_SPACE_FIELD_OPTS,
+			       NULL, 0) != 0) {
 		diag_raise();
 	}
 }
@@ -2382,8 +2382,8 @@ coll_id_def_new_from_tuple(const struct tuple *tuple, struct coll_id_def *def)
 
 	assert(base->type == COLL_TYPE_ICU);
 	if (opts_decode(&base->icu, coll_icu_opts_reg, &options,
-			ER_WRONG_COLLATION_OPTIONS,
-			BOX_COLLATION_FIELD_OPTIONS, NULL) != 0)
+			ER_WRONG_COLLATION_OPTIONS, BOX_COLLATION_FIELD_OPTIONS,
+			NULL, 0) != 0)
 		diag_raise();
 
 	if (base->icu.french_collation == coll_icu_on_off_MAX) {
diff --git a/src/box/key_def.c b/src/box/key_def.c
index ee09dc99d..bc0c1ba35 100644
--- a/src/box/key_def.c
+++ b/src/box/key_def.c
@@ -454,7 +454,7 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count,
 		*part = key_part_def_default;
 		if (opts_decode(part, part_def_reg, data,
 				ER_WRONG_INDEX_OPTIONS, i + TUPLE_INDEX_BASE,
-				NULL) != 0)
+				NULL, 0) != 0)
 			return -1;
 		if (part->type == field_type_MAX) {
 			diag_set(ClientError, ER_WRONG_INDEX_OPTIONS,
diff --git a/src/box/opt_def.c b/src/box/opt_def.c
index cd93c23b8..6710f8187 100644
--- a/src/box/opt_def.c
+++ b/src/box/opt_def.c
@@ -176,13 +176,10 @@ opts_parse_key(void *opts, const struct opt_def *reg, const char *key,
 	return 0;
 }
 
-/**
- * Populate key options from their msgpack-encoded representation
- * (msgpack map).
- */
 int
 opts_decode(void *opts, const struct opt_def *reg, const char **map,
-	    uint32_t errcode, uint32_t field_no, struct region *region)
+	    uint32_t errcode, uint32_t field_no, struct region *region,
+	    uint32_t exact_field_count)
 {
 	assert(mp_typeof(**map) == MP_MAP);
 
@@ -191,6 +188,12 @@ opts_decode(void *opts, const struct opt_def *reg, const char **map,
 	 * DDL is not performance-critical, so this is not a problem.
 	 */
 	uint32_t map_size = mp_decode_map(map);
+	if (map_size != exact_field_count && exact_field_count != 0) {
+		diag_set(ClientError, errcode, field_no,
+			 tt_sprintf("expected %u keys but got %u",
+				    exact_field_count, map_size));
+		return -1;
+	}
 	for (uint32_t i = 0; i < map_size; i++) {
 		if (mp_typeof(**map) != MP_STR) {
 			diag_set(ClientError, errcode, field_no,
diff --git a/src/box/opt_def.h b/src/box/opt_def.h
index 633832af9..4cfebf62a 100644
--- a/src/box/opt_def.h
+++ b/src/box/opt_def.h
@@ -83,10 +83,24 @@ struct region;
 /**
  * Populate key options from their msgpack-encoded representation
  * (msgpack map).
+ * @param[out] opts Where decode options to.
+ * @param reg Field definitions array.
+ * @param map MessagePack to decode.
+ * @param errcode Error code to set on any error. The error code
+ *        has to accept field number and description as
+ *        parameters.
+ * @param field_no Field number to set for @a errcode.
+ * @param region Region for dynamic allocations such as strings.
+ * @param exact_field_count If non-zero, then @a map should
+ *        contain exactly this count of fields.
+ *
+ * @retval 0 Success.
+ * @retval -1 Error.
  */
 int
 opts_decode(void *opts, const struct opt_def *reg, const char **map,
-	    uint32_t errcode, uint32_t field_no, struct region *region);
+	    uint32_t errcode, uint32_t field_no, struct region *region,
+	    uint32_t exact_field_count);
 
 /**
  * Decode one option and store it into @a opts struct as a field.
-- 
2.15.2 (Apple Git-101.1)

  parent reply	other threads:[~2018-08-07 22:03 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-07 22:03 [PATCH 0/8] box.ctl.promote Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 1/8] rfc: describe box.ctl.promote protocol Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 2/8] box: rename process_rw to process_dml Vladislav Shpilevoy
2018-08-13  8:20   ` Vladimir Davydov
2018-08-07 22:03 ` Vladislav Shpilevoy [this message]
2018-08-13  8:30   ` [PATCH 3/8] Add 'exact_field_count' parameter to options decoder Vladimir Davydov
2018-08-07 22:03 ` [PATCH 4/8] box: remove orphan check from box_is_ro() Vladislav Shpilevoy
2018-08-13  8:34   ` Vladimir Davydov
2018-08-07 22:03 ` [PATCH 5/8] Fix gcov on Mac Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 6/8] box: introduce _promotion space Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 7/8] box: introduce box.ctl.promote Vladislav Shpilevoy
2018-08-13  8:58   ` Vladimir Davydov
2018-08-07 22:03 ` [PATCH 8/8] box: introduce promotion GC Vladislav Shpilevoy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eb2fd1e6f6c7bc44310014ce6277bb926e7e0fe2.1533679264.git.v.shpilevoy@tarantool.org \
    --to=v.shpilevoy@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [PATCH 3/8] Add '\''exact_field_count'\'' parameter to options decoder' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox