diff --git a/changelogs/unreleased/gh-5444-relax-uuid-validation.md b/changelogs/unreleased/gh-5444-relax-uuid-validation.md new file mode 100644 index 000000000000..43ae49706403 --- /dev/null +++ b/changelogs/unreleased/gh-5444-relax-uuid-validation.md @@ -0,0 +1,4 @@ +## feature/core + +* Any 128-byte sequence is considered as a valid UUID value to support all + RFC 9562 UUID versions (gh-5444). diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 67f87ce64432..86fc2bf9bfd3 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -812,8 +812,7 @@ static inline int bin_to_uuid(struct Mem *mem) { assert(mem->type == MEM_TYPE_BIN); - if (mem->n != UUID_LEN || - tt_uuid_validate((struct tt_uuid *)mem->z) != 0) + if (mem->n != UUID_LEN) return -1; mem_set_uuid(mem, (struct tt_uuid *)mem->z); return 0; diff --git a/src/lib/core/mp_uuid.c b/src/lib/core/mp_uuid.c index b2341ae36567..9dcb6fd09a6f 100644 --- a/src/lib/core/mp_uuid.c +++ b/src/lib/core/mp_uuid.c @@ -55,7 +55,6 @@ uuid_pack(char *data, const struct tt_uuid *uuid) struct tt_uuid * uuid_unpack(const char **data, uint32_t len, struct tt_uuid *uuid) { - const char *const svp = *data; if (len != UUID_PACKED_LEN) return NULL; uuid->time_low = mp_load_u32(data); @@ -66,10 +65,6 @@ uuid_unpack(const char **data, uint32_t len, struct tt_uuid *uuid) for (int i = 0; i < 6; i++) uuid->node[i] = mp_load_u8(data); - if (tt_uuid_validate(uuid) != 0) { - *data = svp; - return NULL; - } return uuid; } diff --git a/src/lib/core/tt_uuid.c b/src/lib/core/tt_uuid.c index d92376650ce7..a0a6279b6727 100644 --- a/src/lib/core/tt_uuid.c +++ b/src/lib/core/tt_uuid.c @@ -65,9 +65,6 @@ tt_uuid_create(struct tt_uuid *uu) } #endif -extern inline int -tt_uuid_validate(struct tt_uuid *uu); - extern inline int tt_uuid_from_string(const char *in, struct tt_uuid *uu); diff --git a/src/lib/core/tt_uuid.h b/src/lib/core/tt_uuid.h index 70c3b98b10f5..2c58768c4ddb 100644 --- a/src/lib/core/tt_uuid.h +++ b/src/lib/core/tt_uuid.h @@ -62,16 +62,6 @@ struct tt_uuid { void tt_uuid_create(struct tt_uuid *uu); -inline int -tt_uuid_validate(struct tt_uuid *uu) -{ - /* Check variant (NCS, RFC4122, MSFT) */ - uint8_t n = uu->clock_seq_hi_and_reserved; - if ((n & 0x80) != 0x00 && (n & 0xc0) != 0x80 && (n & 0xe0) != 0xc0) - return 1; - return 0; -} - /** * \brief Parse UUID from string. * \param in string @@ -88,8 +78,7 @@ tt_uuid_from_string(const char *in, struct tt_uuid *uu) &uu->node[0], &uu->node[1], &uu->node[2], &uu->node[3], &uu->node[4], &uu->node[5]) != 11) return 1; - - return tt_uuid_validate(uu); + return 0; } /** diff --git a/test/app-luatest/gh_5444_relax_uuid_validation_test.lua b/test/app-luatest/gh_5444_relax_uuid_validation_test.lua new file mode 100644 index 000000000000..636405fcda89 --- /dev/null +++ b/test/app-luatest/gh_5444_relax_uuid_validation_test.lua @@ -0,0 +1,46 @@ +local uuid = require('uuid') +local msgpack = require('msgpack') +local t = require('luatest') + +local group_versions = t.group('group_versions', { + -- UUID examples taken from the RFC 9562 edition: + -- https://datatracker.ietf.org/doc/html/rfc9562#name-test-vectors + + -- The v2 implementation is not specified. Thus, it is + -- omitted here. + {version = 'v1', uuid = 'c232ab00-9414-11ec-b3c8-9f6bdeced846'}, + {version = 'v3', uuid = '5df41881-3aed-3515-88a7-2f4a814cf09e'}, + {version = 'v4', uuid = '919108f7-52d1-4320-9bac-f847db4148a8'}, + {version = 'v5', uuid = '2ed6657d-e927-568b-95e1-2665a8aea6a2'}, + {version = 'v6', uuid = '1ec9414c-232a-6b00-b3c8-9f6bdeced846'}, + {version = 'v7', uuid = '017f22e2-79b0-7cc3-98c4-dc0c0c07398f'}, + {version = 'v8_time_based', uuid = '2489e9ad-2ee2-8e00-8ec9-32d5f69181c0'}, + {version = 'v8_name_based', uuid = '5c146b14-3c52-8afd-938a-375d0df1fbf6'}, +}) + +-- Base test. +group_versions.test_version = function(cg) + local version = cg.params.version + local u = cg.params.uuid + t.assert(uuid.fromstr(u), + ('UUID %s value (%s) failed to parse'):format(version, u)) +end + +local group_gh_5444 = t.group('group_gh_5444', { + {uuid = 'bea80698-e07d-11ea-fe85-00155d373b0c'}, + {uuid = 'bee815b2-e07d-11ea-fe85-00155d373b0c'}, + {uuid = '4429d312-18d4-11eb-94f6-77e22d44915a'}, + {uuid = '64ecacb4-18d4-11eb-94f6-cbb989f20a7e'}, + {uuid = '64ecacb5-18d4-11eb-94f6-cf778123fd70'}, + {uuid = '00000000-0000-0000-e000-000000000000'}, + {uuid = '98c0cfc3-2b03-461d-b662-9a869bf46c75'}, +}) + +-- Test all examples from gh-5444. +group_gh_5444.test_all_examples = function(cg) + local u = cg.params.uuid + local uuid_cdata = uuid.fromstr(u) + t.assert(uuid_cdata, ('UUID value (%s) failed to parse'):format(u)) + t.assert(msgpack.decode(msgpack.encode(uuid_cdata)), + ('UUID value (%s) failed to be decoded in msgpack'):format(u)) +end diff --git a/tools/tarantool-gdb.py b/tools/tarantool-gdb.py index dc924af63d6e..e0f5d328c1f4 100644 --- a/tools/tarantool-gdb.py +++ b/tools/tarantool-gdb.py @@ -544,8 +544,6 @@ def decode_uuid(cls, data, len): # uuid_unpack clock_seq_low = data.read_u8(), node = [ data.read_u8() for _ in range(0, 6) ], )) - if not uuid.is_valid(): - return uuid, "uuid_unpack: invalid uuid" return uuid, None @classmethod @@ -998,12 +996,6 @@ class Uuid: def __init__(self, val): self.val = val - def is_valid(self): # tt_uuid_validate - n = self.val['clock_seq_hi_and_reserved'] - if (n & 0x80) != 0x00 and (n & 0xc0) != 0x80 and (n & 0xe0) != 0xc0: - return False - return True - def __str__(self): # tt_uuid_to_string return '{:08x}-{:04x}-{:04x}-{:02x}{:02x}-{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}'.format( self.val['time_low'], self.val['time_mid'], self.val['time_hi_and_version'],