* [PATCH] uuid: Added l_uuid_parse
@ 2019-02-01 13:46 =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 16:15 ` Marcel Holtmann
2019-02-01 17:22 ` Denis Kenzior
0 siblings, 2 replies; 10+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 13:46 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 5235 bytes --]
From: Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
This commit adds API complementary to l_uuid_to_string, allowing parsing
canonical string representation into a byte array.
I've also changed printf/scanf formatting to use PRIx/SCNx macros, for
better portability.
---
ell/uuid.c | 54 ++++++++++++++++++++++++++++++++++++-------
ell/uuid.h | 1 +
unit/test-uuid.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 8 deletions(-)
diff --git a/ell/uuid.c b/ell/uuid.c
index a4d72fc..26893a5 100644
--- a/ell/uuid.c
+++ b/ell/uuid.c
@@ -25,6 +25,7 @@
#endif
#define _GNU_SOURCE
+#include <inttypes.h>
#include <stdio.h>
#include "checksum.h"
@@ -210,17 +211,54 @@ LIB_EXPORT bool l_uuid_to_string(const uint8_t uuid[16],
{
int n;
- n = snprintf(dest, dest_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
- "%02x%02x-%02x%02x%02x%02x%02x%02x",
- uuid[0], uuid[1], uuid[2], uuid[3],
- uuid[4], uuid[5],
- uuid[6], uuid[7],
- uuid[8], uuid[9],
- uuid[10], uuid[11], uuid[12],
- uuid[13], uuid[14], uuid[15]);
+ n = snprintf(dest, dest_size,
+ "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "-"
+ "%02" PRIx8 "%02" PRIx8 "-"
+ "%02" PRIx8 "%02" PRIx8 "-"
+ "%02" PRIx8 "%02" PRIx8 "-"
+ "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "",
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5],
+ uuid[6], uuid[7],
+ uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
if (n < 0 || (size_t) n >= dest_size)
return false;
return true;
}
+
+LIB_EXPORT bool l_uuid_parse(const char *src, size_t src_size,
+ uint8_t uuid[16])
+{
+ uint8_t buf[16];
+ int n;
+
+ /*
+ * textual representation: 32 hex digits + 4 group separators
+ */
+ if (src_size != 16 * 2 + 4)
+ return false;
+
+ n = sscanf(src,
+ "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "-"
+ "%02" SCNx8 "%02" SCNx8 "-"
+ "%02" SCNx8 "%02" SCNx8 "-"
+ "%02" SCNx8 "%02" SCNx8 "-"
+ "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "%02" SCNx8 "",
+ &buf[0], &buf[1], &buf[2], &buf[3],
+ &buf[4], &buf[5],
+ &buf[6], &buf[7],
+ &buf[8], &buf[9],
+ &buf[10], &buf[11], &buf[12], &buf[13], &buf[14], &buf[15]);
+
+ if (n != 16)
+ return false;
+
+ if (!l_uuid_is_valid(buf))
+ return false;
+
+ memcpy(uuid, buf, sizeof(buf));
+ return true;
+}
diff --git a/ell/uuid.h b/ell/uuid.h
index 89be520..1cb7923 100644
--- a/ell/uuid.h
+++ b/ell/uuid.h
@@ -53,6 +53,7 @@ bool l_uuid_is_valid(const uint8_t uuid[16]);
enum l_uuid_version l_uuid_get_version(const uint8_t uuid[16]);
bool l_uuid_to_string(const uint8_t uuid[16], char *dest, size_t dest_size);
+bool l_uuid_parse(const char *src, size_t src_size, uint8_t uuid[16]);
#ifdef __cplusplus
}
diff --git a/unit/test-uuid.c b/unit/test-uuid.c
index 088d45c..5a4650d 100644
--- a/unit/test-uuid.c
+++ b/unit/test-uuid.c
@@ -158,6 +158,61 @@ static void test_to_string(const void *data)
assert(!strcmp(buf, expected_uuid));
}
+static void test_parse_too_short(const void *data)
+{
+ uint8_t uuid[16];
+ const char *string_uuid = "65fcc697-0776-5bf9-8573-72a51080c7d";
+ bool r;
+
+ r = l_uuid_parse(string_uuid, strlen(string_uuid), uuid);
+ assert(!r);
+}
+
+static void test_parse_too_long(const void *data)
+{
+ uint8_t uuid[16];
+ const char *string_uuid = "65fcc697-0776-5bf9-8573-72a51080c7detoolong";
+ bool r;
+
+ r = l_uuid_parse(string_uuid, strlen(string_uuid), uuid);
+ assert(!r);
+}
+
+static void test_parse_invalid_variant(const void *data)
+{
+ uint8_t uuid[16];
+ const char *string_uuid = "65fcc697-0776-5bf9-c573-72a51080c7de";
+ bool r;
+
+ r = l_uuid_parse(string_uuid, strlen(string_uuid), uuid);
+ assert(!r);
+}
+
+static void test_parse_invalid_hex(const void *data)
+{
+ uint8_t uuid[16];
+ const char *string_uuid = "65fcc697-this-isno-tava-lidhexstring";
+ bool r;
+
+ r = l_uuid_parse(string_uuid, strlen(string_uuid), uuid);
+ assert(!r);
+}
+
+static void test_parse(const void *data)
+{
+ uint8_t uuid[16];
+ bool r;
+ const char *string_uuid = "65fcc697-0776-5bf9-8573-72a51080c7de";
+ uint8_t expected_uuid[16] = { 0x65, 0xfc, 0xc6, 0x97, 0x07, 0x76, 0x5b, 0xf9,
+ 0x85, 0x73, 0x72, 0xa5, 0x10, 0x80, 0xc7, 0xde };
+
+ r = l_uuid_parse(string_uuid, strlen(string_uuid), uuid);
+ assert(r);
+
+ assert(!memcmp(uuid, expected_uuid, sizeof(uuid)));
+
+}
+
int main(int argc, char *argv[])
{
l_test_init(&argc, &argv);
@@ -169,6 +224,11 @@ int main(int argc, char *argv[])
l_test_add("/uuid/v5", test_v5, NULL);
l_test_add("/uuid/to string", test_to_string, NULL);
+ l_test_add("/uuid/parse too short", test_parse_too_short, NULL);
+ l_test_add("/uuid/parse too long", test_parse_too_long, NULL);
+ l_test_add("/uuid/parse invalid variant", test_parse_invalid_variant, NULL);
+ l_test_add("/uuid/parse invalid hex", test_parse_invalid_hex, NULL);
+ l_test_add("/uuid/parse", test_parse, NULL);
return l_test_run();
--
2.19.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 13:46 [PATCH] uuid: Added l_uuid_parse =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
@ 2019-02-01 16:15 ` Marcel Holtmann
2019-02-01 17:22 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:22 ` Denis Kenzior
1 sibling, 1 reply; 10+ messages in thread
From: Marcel Holtmann @ 2019-02-01 16:15 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 2315 bytes --]
Hi Michal,
> This commit adds API complementary to l_uuid_to_string, allowing parsing
> canonical string representation into a byte array.
I would have called it l_uuid_from_string.
> I've also changed printf/scanf formatting to use PRIx/SCNx macros, for
> better portability.
This should be a separate patch.
> ---
> ell/uuid.c | 54 ++++++++++++++++++++++++++++++++++++-------
> ell/uuid.h | 1 +
> unit/test-uuid.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 107 insertions(+), 8 deletions(-)
>
> diff --git a/ell/uuid.c b/ell/uuid.c
> index a4d72fc..26893a5 100644
> --- a/ell/uuid.c
> +++ b/ell/uuid.c
> @@ -25,6 +25,7 @@
> #endif
>
> #define _GNU_SOURCE
> +#include <inttypes.h>
> #include <stdio.h>
>
> #include "checksum.h"
> @@ -210,17 +211,54 @@ LIB_EXPORT bool l_uuid_to_string(const uint8_t uuid[16],
> {
> int n;
>
> - n = snprintf(dest, dest_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
> - "%02x%02x-%02x%02x%02x%02x%02x%02x",
> - uuid[0], uuid[1], uuid[2], uuid[3],
> - uuid[4], uuid[5],
> - uuid[6], uuid[7],
> - uuid[8], uuid[9],
> - uuid[10], uuid[11], uuid[12],
> - uuid[13], uuid[14], uuid[15]);
> + n = snprintf(dest, dest_size,
> + "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "-"
> + "%02" PRIx8 "%02" PRIx8 "-"
> + "%02" PRIx8 "%02" PRIx8 "-"
> + "%02" PRIx8 "%02" PRIx8 "-"
> + "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "",
> + uuid[0], uuid[1], uuid[2], uuid[3],
> + uuid[4], uuid[5],
> + uuid[6], uuid[7],
> + uuid[8], uuid[9],
> + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
>
> if (n < 0 || (size_t) n >= dest_size)
> return false;
>
> return true;
> }
> +
> +LIB_EXPORT bool l_uuid_parse(const char *src, size_t src_size,
> + uint8_t uuid[16])
> +{
Don’t bother with src_size parameter. You can use strlen for that since supporting non null-terminated strings seems rather pointless. You will required space or null terminator at the end of make sscanf actually work correctly anyway. So I would rather check that the string is long enough to hold an actual UUID text representation and that you have a proper terminator at the end.
Regards
Marcel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 13:46 [PATCH] uuid: Added l_uuid_parse =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 16:15 ` Marcel Holtmann
@ 2019-02-01 17:22 ` Denis Kenzior
2019-02-01 17:28 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 21:14 ` Jan Engelhardt
1 sibling, 2 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-02-01 17:22 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 508 bytes --]
Hi Michał,
> I've also changed printf/scanf formatting to use PRIx/SCNx macros, for
> better portability
Hmm, portability where? Is this an actual concern? Any platform that
ell can actually run on, PRIx/SCNx == 'x', no?
The use of PRI* macros makes the printf statement quite a bit less
readable IMO. I can understand the need when using size_t or other
esoteric types that depend on the arch, but uint8_t isn't one of them...
Anyway, no biggie, just wondering...
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 16:15 ` Marcel Holtmann
@ 2019-02-01 17:22 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:25 ` Denis Kenzior
0 siblings, 1 reply; 10+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 17:22 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 1217 bytes --]
Hi Marcel,
Thanks for the review. I'll change the name and extract formatting
macros to a separate commit.
On 02/01, Marcel Holtmann wrote:
> > +LIB_EXPORT bool l_uuid_parse(const char *src, size_t src_size,
> > + uint8_t uuid[16])
> > +{
>
> Don’t bother with src_size parameter. You can use strlen for that
> since supporting non null-terminated strings seems rather pointless.
> You will required space or null terminator at the end of make sscanf
> actually work correctly anyway. So I would rather check that the
> string is long enough to hold an actual UUID text representation and
> that you have a proper terminator at the end.
I don't think that's true. Since format passed to scanf expects a fixed
input length, this works as expected:
const char *string_uuid = "65fcc697-0776-5bf9-8573-72a51080c7detoolong";
l_uuid_parse(string_uuid, strlen(string_uuid) - strlen('toolong'), uuid);
The use case would be retrieving the UUID from a substring (at given
offset), e.g. from a path. I'll add the unit test for this.
regards
--
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 17:22 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
@ 2019-02-01 17:25 ` Denis Kenzior
2019-02-01 17:29 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
0 siblings, 1 reply; 10+ messages in thread
From: Denis Kenzior @ 2019-02-01 17:25 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 635 bytes --]
Hi Michał,
> I don't think that's true. Since format passed to scanf expects a fixed
> input length, this works as expected:
>
> const char *string_uuid = "65fcc697-0776-5bf9-8573-72a51080c7detoolong";
> l_uuid_parse(string_uuid, strlen(string_uuid) - strlen('toolong'), uuid);
>
> The use case would be retrieving the UUID from a substring (at given
> offset), e.g. from a path. I'll add the unit test for this.
But then you know the expected UUID length anyway. So you can simply
check that strlen(string_uuid) is at least that long and pass in the
expected UUID length to sscanf.
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 17:22 ` Denis Kenzior
@ 2019-02-01 17:28 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:33 ` Denis Kenzior
2019-02-01 21:14 ` Jan Engelhardt
1 sibling, 1 reply; 10+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 17:28 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 628 bytes --]
Hi Denis.
On 02/01, Denis Kenzior wrote:
> Hmm, portability where? Is this an actual concern? Any platform that ell
> can actually run on, PRIx/SCNx == 'x', no?
You're right about PRIx, but it's different for SCN:
#include <stdio.h>
#include <inttypes.h>
int main()
{
printf("PRIx8=%s, SCNx8=%s\n", PRIx8 "", SCNx8 "");
}
$ ./a.out
PRIx8=x, SCNx8=hhx
I'll drop the change in l_uuid_to_string, but I'd like to keep SCNx,
even though it indeed does look messy.
--
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 17:25 ` Denis Kenzior
@ 2019-02-01 17:29 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
0 siblings, 0 replies; 10+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 17:29 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 441 bytes --]
Hi Denis,
On 02/01, Denis Kenzior wrote:
> But then you know the expected UUID length anyway. So you can simply check
> that strlen(string_uuid) is at least that long and pass in the expected UUID
> length to sscanf.
You're right, of course. Silly me. I'll fix the patch accordingly,
thanks.
--
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 17:28 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
@ 2019-02-01 17:33 ` Denis Kenzior
2019-02-01 17:39 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
0 siblings, 1 reply; 10+ messages in thread
From: Denis Kenzior @ 2019-02-01 17:33 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 218 bytes --]
Hi Michał,
> $ ./a.out
> PRIx8=x, SCNx8=hhx
Ah right. But then I would just use hhx instead of SCNx8. There should
be no portability concerns and it is makes things much more readable.
Regards,
-Denis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 17:33 ` Denis Kenzior
@ 2019-02-01 17:39 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
0 siblings, 0 replies; 10+ messages in thread
From: =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek @ 2019-02-01 17:39 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 462 bytes --]
Denis,
On 02/01, Denis Kenzior wrote:
> Hi Michał,
>
> > $ ./a.out
> > PRIx8=x, SCNx8=hhx
>
> Ah right. But then I would just use hhx instead of SCNx8. There should be
> no portability concerns and it is makes things much more readable.
Ok, will do.
Too much bare metal does something to one's brain...
--
Michał Lowas-Rzechonek <michal.lowas-rzechonek@silvair.com>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] uuid: Added l_uuid_parse
2019-02-01 17:22 ` Denis Kenzior
2019-02-01 17:28 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
@ 2019-02-01 21:14 ` Jan Engelhardt
1 sibling, 0 replies; 10+ messages in thread
From: Jan Engelhardt @ 2019-02-01 21:14 UTC (permalink / raw)
To: ell
[-- Attachment #1: Type: text/plain, Size: 639 bytes --]
On Friday 2019-02-01 18:22, Denis Kenzior wrote:
> Hi Michał,
>
>> I've also changed printf/scanf formatting to use PRIx/SCNx macros, for
>> better portability
>
> Hmm, portability where? Is this an actual concern? Any platform that ell can
> actually run on, PRIx/SCNx == 'x', no?
>
> The use of PRI* macros makes the printf statement quite a bit less readable
> IMO. I can understand the need when using size_t or other esoteric types that
> depend on the arch, but uint8_t isn't one of them...
size_t isn't esoteric, it has its own standard specifier, %zu.
Unless, of course, you're somehow depending on MSVCRT6...
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-02-01 21:14 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-01 13:46 [PATCH] uuid: Added l_uuid_parse =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 16:15 ` Marcel Holtmann
2019-02-01 17:22 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:25 ` Denis Kenzior
2019-02-01 17:29 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:22 ` Denis Kenzior
2019-02-01 17:28 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 17:33 ` Denis Kenzior
2019-02-01 17:39 ` =?unknown-8bit?q?Micha=C5=82?= 'Khorne' Lowas-Rzechonek
2019-02-01 21:14 ` Jan Engelhardt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.