diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 26521661b7f205db48eac5503c0d1bab69eac315..d3d2bb5c07b31bafb6a68c57e887da801d2824a6 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.230 2008/10/14 17:12:32 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.231 2008/11/03 22:14:40 petere Exp $ --> <chapter id="datatype"> <title id="datatype-title">Data Types</title> @@ -3550,11 +3550,14 @@ a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 <productname>PostgreSQL</productname> also accepts the following alternative forms for input: use of upper-case digits, the standard format surrounded by - braces, and omitting the hyphens. Examples are: + braces, omitting some or all hyphens, adding a hyphen after any + group of four digits. Examples are: <programlisting> A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11 {a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11} a0eebc999c0b4ef8bb6d6bb9bd380a11 +a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 +{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11} </programlisting> Output is always in the standard form. </para> diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index 216546e5206621fd6106c6046802a8d13158262e..76a012ed57779e3e647d7ba7318432a05c5fad54 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: