From 25ce4c1c0cdd8fd6f356b00b1653a4f9dd541332 Mon Sep 17 00:00:00 2001 From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Date: Tue, 11 Jul 2017 17:20:34 +0300 Subject: [PATCH] schema: decrease BOX_NAME_MAX usage Do not use BOX_NAME_MAX as size of static buffers. Further it will be strongly increased. Part of #944 --- src/box/box.cc | 56 ++++++++++++++++++++++++++-------------------- src/box/key_def.cc | 4 ++-- src/box/key_def.h | 2 ++ src/box/schema.cc | 26 ++++++++++++--------- src/box/user.cc | 5 +---- 5 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/box/box.cc b/src/box/box.cc index 6c149f163d..1dfd1a8bb7 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -666,49 +666,58 @@ box_return_tuple(box_function_ctx_t *ctx, box_tuple_t *tuple) uint32_t box_space_id_by_name(const char *name, uint32_t len) { - char buf[1 + 5 + BOX_NAME_MAX + 5]; if (len > BOX_NAME_MAX) return BOX_ID_NIL; - - char *p = buf; - p = mp_encode_array(p, 1); - p = mp_encode_str(p, name, len); - assert(p < buf + sizeof(buf)); + uint32_t size = mp_sizeof_array(1) + mp_sizeof_str(len); + struct region *region = &fiber()->gc; + uint32_t used = region_used(region); + char *begin = (char *) region_alloc(region, size); + if (begin == NULL) { + diag_set(OutOfMemory, size, "region_alloc", "begin"); + return BOX_ID_NIL; + } + auto guard = make_scoped_guard([=] { region_truncate(region, used); }); + char *end = mp_encode_array(begin, 1); + end = mp_encode_str(end, name, len); /* NOTE: error and missing key cases are indistinguishable */ box_tuple_t *tuple; - if (box_index_get(BOX_VSPACE_ID, 2, buf, p, &tuple) != 0) + if (box_index_get(BOX_VSPACE_ID, 2, begin, end, &tuple) != 0) return BOX_ID_NIL; if (tuple == NULL) return BOX_ID_NIL; - uint32_t result; - if (tuple_field_u32(tuple, BOX_SPACE_FIELD_ID, &result) != 0) - return BOX_ID_NIL; + uint32_t result = BOX_ID_NIL; + (void) tuple_field_u32(tuple, BOX_SPACE_FIELD_ID, &result); return result; } uint32_t box_index_id_by_name(uint32_t space_id, const char *name, uint32_t len) { - char buf[1 + 5 + BOX_NAME_MAX + 5]; if (len > BOX_NAME_MAX) return BOX_ID_NIL; - - char *p = buf; - p = mp_encode_array(p, 2); - p = mp_encode_uint(p, space_id); - p = mp_encode_str(p, name, len); - assert(p < buf + sizeof(buf)); + uint32_t size = mp_sizeof_array(2) + mp_sizeof_uint(space_id) + + mp_sizeof_str(len); + struct region *region = &fiber()->gc; + uint32_t used = region_used(region); + char *begin = (char *) region_alloc(region, size); + if (begin == NULL) { + diag_set(OutOfMemory, size, "region_alloc", "begin"); + return BOX_ID_NIL; + } + auto guard = make_scoped_guard([=] { region_truncate(region, used); }); + char *end = mp_encode_array(begin, 2); + end = mp_encode_uint(end, space_id); + end = mp_encode_str(end, name, len); /* NOTE: error and missing key cases are indistinguishable */ box_tuple_t *tuple; - if (box_index_get(BOX_VINDEX_ID, 2, buf, p, &tuple) != 0) + if (box_index_get(BOX_VINDEX_ID, 2, begin, end, &tuple) != 0) return BOX_ID_NIL; if (tuple == NULL) return BOX_ID_NIL; - uint32_t result; - if (tuple_field_u32(tuple, BOX_INDEX_FIELD_ID, &result) != 0) - return BOX_ID_NIL; + uint32_t result = BOX_ID_NIL; + (void) tuple_field_u32(tuple, BOX_INDEX_FIELD_ID, &result); return result; } /** \endcond public */ @@ -931,11 +940,10 @@ access_check_func(const char *name, uint32_t name_len) if (func == NULL || (func->def->uid != credentials->uid && access & ~func->access[credentials->auth_token].effective)) { /* Access violation, report error. */ - char name_buf[BOX_NAME_MAX + 1]; - snprintf(name_buf, sizeof(name_buf), "%.*s", name_len, name); struct user *user = user_find_xc(credentials->uid); tnt_raise(ClientError, ER_FUNCTION_ACCESS_DENIED, - priv_name(access), user->def->name, name_buf); + priv_name(access), user->def->name, + tt_cstr(name, name_len)); } return func; diff --git a/src/box/key_def.cc b/src/box/key_def.cc index 0124b1d4ec..bc57189581 100644 --- a/src/box/key_def.cc +++ b/src/box/key_def.cc @@ -496,7 +496,7 @@ key_def_encode_parts(char *data, const struct key_def *key_def) int key_def_decode_parts(struct key_def *key_def, const char **data) { - char buf[BOX_NAME_MAX]; + char buf[FIELD_TYPE_NAME_MAX]; for (uint32_t i = 0; i < key_def->part_count; i++) { if (mp_typeof(**data) != MP_ARRAY) { diag_set(ClientError, ER_WRONG_INDEX_PARTS, @@ -544,7 +544,7 @@ key_def_decode_parts(struct key_def *key_def, const char **data) int key_def_decode_parts_165(struct key_def *key_def, const char **data) { - char buf[BOX_NAME_MAX]; + char buf[FIELD_TYPE_NAME_MAX]; for (uint32_t i = 0; i < key_def->part_count; i++) { uint32_t field_no = (uint32_t) mp_decode_uint(data); uint32_t len; diff --git a/src/box/key_def.h b/src/box/key_def.h index 7b766d1998..cd19fa29fd 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -52,6 +52,8 @@ enum { BOX_INDEX_MAX = 128, BOX_NAME_MAX = 64, ENGINE_NAME_MAX = 16, + FIELD_TYPE_NAME_MAX = 16, + GRANT_NAME_MAX = 16, BOX_FIELD_MAX = INT32_MAX, BOX_USER_MAX = 32, /** diff --git a/src/box/schema.cc b/src/box/schema.cc index f36f2176dd..1e5d726162 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -210,20 +210,19 @@ uint32_t schema_find_id(uint32_t system_space_id, uint32_t index_id, const char *name, uint32_t len) { + if (len > BOX_NAME_MAX) + return BOX_ID_NIL; struct space *space = space_cache_find(system_space_id); MemtxIndex *index = index_find_system(space, index_id); - char buf[BOX_NAME_MAX * 2]; - /** - * This is an internal-only method, we should know the - * max length in advance. - */ - if (len + 5 > sizeof(buf)) - return BOX_ID_NIL; - - mp_encode_str(buf, name, len); + uint32_t size = mp_sizeof_str(len); + struct region *region = &fiber()->gc; + uint32_t used = region_used(region); + char *key = (char *) region_alloc_xc(region, size); + auto guard = make_scoped_guard([=] { region_truncate(region, used); }); + mp_encode_str(key, name, len); struct iterator *it = index->position(); - index->initIterator(it, ITER_EQ, buf, 1); + index->initIterator(it, ITER_EQ, key, 1); struct tuple *tuple = it->next(it); if (tuple) { @@ -440,7 +439,12 @@ schema_find_grants(const char *type, uint32_t id) /** "object" index */ MemtxIndex *index = index_find_system(priv, 2); struct iterator *it = index->position(); - char key[10 + BOX_NAME_MAX]; + /* + * +10 = max(mp_sizeof_uint32) + + * max(mp_sizeof_strl(uint32)). + */ + char key[GRANT_NAME_MAX + 10]; + assert(strlen(type) <= GRANT_NAME_MAX); mp_encode_uint(mp_encode_str(key, type, strlen(type)), id); index->initIterator(it, ITER_EQ, key, 2); return it->next(it); diff --git a/src/box/user.cc b/src/box/user.cc index 4bd96af6a6..dfde8a019f 100644 --- a/src/box/user.cc +++ b/src/box/user.cc @@ -442,10 +442,7 @@ user_find_by_name(const char *name, uint32_t len) uint32_t uid = schema_find_id(BOX_USER_ID, 2, name, len); struct user *user = user_by_id(uid); if (user == NULL || user->def->type != SC_USER) { - char name_buf[BOX_NAME_MAX + 1]; - /* \0 - to correctly print user name the error message. */ - snprintf(name_buf, sizeof(name_buf), "%.*s", len, name); - diag_set(ClientError, ER_NO_SUCH_USER, name_buf); + diag_set(ClientError, ER_NO_SUCH_USER, tt_cstr(name, len)); return NULL; } return user; -- GitLab