From: Nathan Wagner Date: Thu, 13 Sep 2012 23:41:11 +0000 (+0000) Subject: Fixed segfault in v1mc() and added test cases. X-Git-Url: https://pd.if.org/git/?p=uuid;a=commitdiff_plain;h=6c2a66816de51f195e4cae40406834f519768099 Fixed segfault in v1mc() and added test cases. --- diff --git a/Makefile b/Makefile index f2e67a9..348c3aa 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,8 @@ libpduuid.a: $(OBJ) ar rcuv $@ $+ ranlib $@ -t/%.t: t/%.o t/ctap.o - $(CC) $(CFLAGS) -Wall -I. -o $@ $+ -lpduuid +t/%.t: t/%.o t/ctap.o libpduuid.a + $(CC) $(CFLAGS) -Wall -I. -o $@ $< t/ctap.o -lpduuid test: t/uuidgen.t libpduuid.a prove t/*.t diff --git a/internal.c b/internal.c index ef0115b..02f3e87 100644 --- a/internal.c +++ b/internal.c @@ -370,30 +370,60 @@ int pd_uuid_make_v1(struct pd_uuid_state *s, pd_uuid_t *uuid) { return 1; } -int pd_uuid_make_v1mc(struct pd_uuid_state *ps, pd_uuid_t *uuid) { - struct pd_uuid_state s; +int pd_uuid_make_v1mc(struct pd_uuid_state *s, pd_uuid_t *uuid) { + struct pd_uuid_state ls; uint64_t now; uint64_t node; + int err; + + if (!s) { + s = &ls; + pd_uuid_init_state(s); + } + + if (s->get_lock) { + if ((err = s->get_lock(s->lock_data)) != 0) { + /* TODO set uuid to nil ? */ + /* be cute and have an "error" uuid? */ + return 0; + } + } + + if (s->read_state) { + if ((err = s->read_state(s)) != 0) { + return 0; + } + } - obtain_global_lock(0); - read_state(&s); now = current_time(); - node = random_mc_mac(&s); - if (!s.available) { - s.clock_sequence = random_clock_sequence(&s); + node = random_mc_mac(s); + + if (!s->available || s->node != node) { + s->clock_sequence = random_clock_sequence(s); } + s->node = node; - if (s.available && s.timestamp > now) { - s.clock_sequence++; + if (s->available && s->timestamp > now) { + s->clock_sequence++; } else { - s.timestamp = now; + s->timestamp = now; } - save_state(&s); - release_global_lock(0); - s.node = node; + if (s->save_state) { + if ((err = s->save_state(s)) != 0) { + return 0; + } + } + + if (s->release_lock) { + if ((err = s->release_lock(s->lock_data)) != 0) { + /* TODO set uuid to nil ? */ + /* be cute and have an "error" uuid? */ + return 0; + } + } - format_uuid(uuid, &s, 1); + format_uuid(uuid, s, 1); return 1; } diff --git a/t/uuidgen.c b/t/uuidgen.c index 6fb3c56..8a6e45f 100644 --- a/t/uuidgen.c +++ b/t/uuidgen.c @@ -11,6 +11,25 @@ #include "pduuid.h" #include "ctap.h" +static int strbytes(char *s, unsigned char *d) { + unsigned int byte; + int i = 0; + + if (!s) return 0; + if (*s == 0) return 0; + + while (*s) { + if (*s == '-' || *s == ':') s++; + + if (sscanf(s, "%02x", &byte) != 1) { + return 0; + } + s += 2; + d[i++] = byte & 0xff; + } + return i; +} + void ufmt(pd_uuid_t *uuid, char *s) { int i; for (i=0;i<4;i++) { @@ -42,8 +61,11 @@ int str_ok(pd_uuid_t *uuid, char *s, char *name) { } int main(int ac, char *av[]) { - pd_uuid_t uuid; + pd_uuid_t uuid, copy; + struct pd_uuid_state s; + char fmt[37]; + unsigned char hash[40]; char *url = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; char *dns = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; @@ -56,39 +78,80 @@ int main(int ac, char *av[]) { srandom(time(0)); #endif - plan(7); + plan(13); + + pd_uuid_init_state(0); + pd_uuid_make_v1mc(0, &uuid); + + pd_uuid_init_state(&s); + pd_uuid_make_v1mc(&s, &uuid); + + pd_uuid_init_state(&s); pd_uuid_make_v1(0, &uuid); ufmt(&uuid, fmt); diag("v1: %s", fmt); + pd_uuid_make_v1(&s, &uuid); + pd_uuid_init_state(&s); pd_uuid_make_v4(0, &uuid); ufmt(&uuid, fmt); diag("v4: %s", fmt); + pd_uuid_make_v4(&s, &uuid); pd_uuid_set_string(&uuid, "6ba7b810-9dad-11d1-80b4-00c04fd430c8"); ufmt(&uuid, fmt); is_string("6ba7b810-9dad-11d1-80b4-00c04fd430c8", fmt, "t/f string"); ufmt(&pd_uuid_ns_x500, fmt); - is_string(x500, fmt, "pd_uuid_ns_x500()"); + is_string(x500, fmt, "pd_uuid_ns_x500"); ufmt(&pd_uuid_ns_oid, fmt); - is_string(oid, fmt, "pd_uuid_ns_oid()"); + is_string(oid, fmt, "pd_uuid_ns_oid"); ufmt(&pd_uuid_ns_url, fmt); - is_string(url, fmt, "pd_uuid_ns_url()"); + is_string(url, fmt, "pd_uuid_ns_url"); ufmt(&pd_uuid_ns_dns, fmt); - is_string(dns, fmt, "pd_uuid_ns_dns()"); + is_string(dns, fmt, "pd_uuid_ns_dns"); pd_uuid_make_v3(0, &uuid, &pd_uuid_ns_dns, "granicus.if.org", strlen("granicus.if.org")); ufmt(&uuid, fmt); is_string("e6e8e9cb-78bd-33b3-b8ae-d442456e8169", fmt, "granicus.if.org (v3)"); + pd_uuid_init_state(&s); + pd_uuid_make_v3(&s, &uuid, &pd_uuid_ns_dns, "granicus.if.org", strlen("granicus.if.org")); + ufmt(&uuid, fmt); + is_string("e6e8e9cb-78bd-33b3-b8ae-d442456e8169", fmt, "granicus.if.org (v3)"); pd_uuid_make_v5(0, &uuid, &pd_uuid_ns_dns, "granicus.if.org", strlen("granicus.if.org")); ufmt(&uuid, fmt); is_string("fc1d1ec9-f731-5bfb-854e-e38a4dbd9dd3", fmt, "granicus.if.org (v5)"); + pd_uuid_init_state(&s); + pd_uuid_make_v5(&s, &uuid, &pd_uuid_ns_dns, "granicus.if.org", strlen("granicus.if.org")); + ufmt(&uuid, fmt); + is_string("fc1d1ec9-f731-5bfb-854e-e38a4dbd9dd3", fmt, "granicus.if.org (v5)"); + + pd_uuid_copy(&uuid, ©); + ufmt(©, fmt); + is_string("fc1d1ec9-f731-5bfb-854e-e38a4dbd9dd3", fmt, "granicus.if.org (v5)"); + + ok(!pd_uuid_cmp(&uuid, ©), "uuid cmp copy"); + + strbytes("622e4fa57481e7ed5c9119e1ba69bf88255ca4a1", hash); + pd_set_uuid_hash(&uuid, hash, 5); + str_ok(&uuid, "622e4fa5-7481-57ed-9c91-19e1ba69bf88", "set from hash"); + + pd_uuid_rng_get_bytes(hash, 5); + + /* try to get two in very short sequence */ + pd_uuid_init_state(&s); + pd_uuid_make_v1(&s, &uuid); + pd_uuid_make_v1(&s, ©); + ok(pd_uuid_cmp(&uuid, ©), "uuid v1 different"); + ufmt(&uuid, fmt); + diag("v1a: %s", fmt); + ufmt(©, fmt); + diag("v1b: %s", fmt); return 0; }