summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2008-11-03 22:14:40 +0000
committerPeter Eisentraut <peter_e@gmx.net>2008-11-03 22:14:40 +0000
commit84aa797292fab70e5c1bdbd863ff475981d0d22d (patch)
tree92513acdae893c80c41da5c82132ae737962c912 /src/backend/utils/adt
parent48cbe59150de7f8ba8a065b575bb389f0c5c2d7d (diff)
downloadpostgresql-84aa797292fab70e5c1bdbd863ff475981d0d22d.tar.gz
Allow uuid_in() to parse a wider variety of variant input formats for the UUID
data type. This patch takes the approach of allowing an optional hyphen after each group of four hex digits. Author: Robert Haas <robertmhaas@gmail.com>
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r--src/backend/utils/adt/uuid.c61
1 files changed, 26 insertions, 35 deletions
diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c
index 216546e520..76a012ed57 100644
--- a/src/backend/utils/adt/uuid.c
+++ b/src/backend/utils/adt/uuid.c
@@ -6,7 +6,7 @@
* Copyright (c) 2007-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.7 2008/01/01 20:31:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/uuid.c,v 1.8 2008/11/03 22:14:40 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -74,60 +74,51 @@ uuid_out(PG_FUNCTION_ARGS)
}
/*
- * We allow UUIDs in three input formats: 8x-4x-4x-4x-12x,
- * {8x-4x-4x-4x-12x}, and 32x, where "nx" means n hexadecimal digits
- * (only the first format is used for output). We convert the first
- * two formats into the latter format before further processing.
+ * We allow UUIDs as a series of 32 hexadecimal digits with an optional dash
+ * after each group of 4 hexadecimal digits, and optionally surrounded by {}.
+ * (The canonical format 8x-4x-4x-4x-12x, where "nx" means n hexadecimal
+ * digits, is the only one used for output.)
*/
static void
string_to_uuid(const char *source, pg_uuid_t *uuid)
{
- char hex_buf[32]; /* not NUL terminated */
- int i;
- int src_len;
-
- src_len = strlen(source);
- if (src_len != 32 && src_len != 36 && src_len != 38)
- goto syntax_error;
+ const char *src = source;
+ int i, braces = 0;
- if (src_len == 32)
- memcpy(hex_buf, source, src_len);
- else
+ if (src[0] == '{')
{
- const char *str = source;
-
- if (src_len == 38)
- {
- if (str[0] != '{' || str[37] != '}')
- goto syntax_error;
-
- str++; /* skip the first character */
- }
-
- if (str[8] != '-' || str[13] != '-' ||
- str[18] != '-' || str[23] != '-')
- goto syntax_error;
-
- memcpy(hex_buf, str, 8);
- memcpy(hex_buf + 8, str + 9, 4);
- memcpy(hex_buf + 12, str + 14, 4);
- memcpy(hex_buf + 16, str + 19, 4);
- memcpy(hex_buf + 20, str + 24, 12);
+ ++src;
+ braces = 1;
}
for (i = 0; i < UUID_LEN; i++)
{
char str_buf[3];
- memcpy(str_buf, &hex_buf[i * 2], 2);
+ if (src[0] == '\0' || src[1] == '\0')
+ goto syntax_error;
+ memcpy(str_buf, src, 2);
if (!isxdigit((unsigned char) str_buf[0]) ||
!isxdigit((unsigned char) str_buf[1]))
goto syntax_error;
str_buf[2] = '\0';
uuid->data[i] = (unsigned char) strtoul(str_buf, NULL, 16);
+ src += 2;
+ if (src[0] == '-' && (i % 2) == 1 && i < UUID_LEN - 1)
+ src++;
}
+ if (braces)
+ {
+ if (*src!= '}')
+ goto syntax_error;
+ ++src;
+ }
+
+ if (*src != '\0')
+ goto syntax_error;
+
return;
syntax_error: