Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Apr 2020 18:39:13 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r359980 - in head/sys: kern sys
Message-ID:  <202004151839.03FIdDPJ026070@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Wed Apr 15 18:39:12 2020
New Revision: 359980
URL: https://svnweb.freebsd.org/changeset/base/359980

Log:
  validate_uuid: absorb the rest of parse_uuid with a flags arg
  
  This makes the naming annoyance (validate_uuid vs. parse_uuid) less of an
  issue and centralizes all of the functionality into the new KPI while still
  making the extra validation optional. The end-result is all the same as far
  as hostuuid validation-only goes.

Modified:
  head/sys/kern/kern_uuid.c
  head/sys/sys/uuid.h

Modified: head/sys/kern/kern_uuid.c
==============================================================================
--- head/sys/kern/kern_uuid.c	Wed Apr 15 18:27:28 2020	(r359979)
+++ head/sys/kern/kern_uuid.c	Wed Apr 15 18:39:12 2020	(r359980)
@@ -382,13 +382,21 @@ be_uuid_dec(void const *buf, struct uuid *uuid)
 }
 
 int
-validate_uuid(const char *str, size_t size, struct uuid *uuid)
+validate_uuid(const char *str, size_t size, struct uuid *uuid, int flags)
 {
 	u_int c[11];
 	int n;
 
-	if (size == 0 || *str == '\0')
+	if (size == 0 || *str == '\0') {
+		/* An empty string may represent a nil UUID. */
+		if ((flags & VUUIDF_EMPTYOK) != 0) {
+			if (uuid != NULL)
+				bzero(uuid, sizeof(*uuid));
+			return (0);
+		}
+
 		return (EINVAL);
+	}
 
 	/* The UUID string representation has a fixed length. */
 	if (size != 36)
@@ -421,30 +429,21 @@ validate_uuid(const char *str, size_t size, struct uui
 			uuid->node[n] = c[n + 5];
 	}
 
-	return (0);
+	if ((flags & VUUIDF_CHECKSEMANTICS) == 0)
+		return (0);
+
+	return (((c[3] & 0x80) != 0x00 &&		/* variant 0? */
+	    (c[3] & 0xc0) != 0x80 &&			/* variant 1? */
+	    (c[3] & 0xe0) != 0xc0) ? EINVAL : 0);	/* variant 2? */
 }
 
+#define	VUUIDF_PARSEFLAGS	(VUUIDF_EMPTYOK | VUUIDF_CHECKSEMANTICS)
+
 int
 parse_uuid(const char *str, struct uuid *uuid)
 {
-	unsigned int clock_seq;
-	int ret;
 
-	/* An empty string represents a nil UUID. */
-	if (*str == '\0') {
-		bzero(uuid, sizeof(*uuid));
-		return (0);
-	}
-
-	ret = validate_uuid(str, strlen(str), uuid);
-	if (ret != 0)
-		return (ret);
-
-	/* Check semantics... */
-	clock_seq = uuid->clock_seq_hi_and_reserved;
-	return (((clock_seq & 0x80) != 0x00 &&		/* variant 0? */
-	    (clock_seq & 0xc0) != 0x80 &&		/* variant 1? */
-	    (clock_seq & 0xe0) != 0xc0) ? EINVAL : 0);	/* variant 2? */
+	return (validate_uuid(str, strlen(str), uuid, VUUIDF_PARSEFLAGS));
 }
 
 int

Modified: head/sys/sys/uuid.h
==============================================================================
--- head/sys/sys/uuid.h	Wed Apr 15 18:27:28 2020	(r359979)
+++ head/sys/sys/uuid.h	Wed Apr 15 18:39:12 2020	(r359980)
@@ -68,20 +68,18 @@ int printf_uuid(struct uuid *);
 int sbuf_printf_uuid(struct sbuf *, struct uuid *);
 
 /*
- * There are a few key differences between validate_uuid and parse_uuid:
- *
- * - The struct uuid * parameter to validate_uuid is optional, so the caller
- *    can simply validate UUID format without doing anything with the result.
- * - validate_uuid will not pass an empty string as a valid UUID, as it doesn't
- *    strictly meet the formatting requirements.  parse_uuid will accept an
- *    empty string and zero out the uuid struct accordingly.
- * - parse_uuid does additional semantic checks on clock_seq_hi_and_reserved
- *    that validate_uuid will not do.
- *
- * validate_uuid is intended to strictly check that it's a well-formed uuid.
+ * validate_uuid will, with no flags passed, validate only the format of the
+ * passed in UUID.  Flags below are available to give it part of or all of the
+ * functionality that parse_uuid has traditionally had: acknowledging an empty
+ * string as valid, and checking the semantics of the UUID as well.
  */
-int validate_uuid(const char *, size_t, struct uuid *);
+int validate_uuid(const char *, size_t, struct uuid *, int);
 int parse_uuid(const char *, struct uuid *);
+
+/* Flags to validate_uuid(). */
+#define	VUUIDF_EMPTYOK		0x0001
+#define	VUUIDF_CHECKSEMANTICS	0x0002
+
 int uuidcmp(const struct uuid *, const struct uuid *);
 
 void be_uuid_dec(void const *buf, struct uuid *uuid);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004151839.03FIdDPJ026070>