aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-08-14 14:19:11 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-08-14 14:19:11 +0000
commit2b5f049f7c6231cce3d79b8949f7aeee3bb4081a (patch)
tree17e5a48c5a7ceb22f5dd3de33ff7339ee3ccbc72 /src
parent8e97f45f88aeb2ac83cde4910a9216d970a4c0f7 (diff)
downloadpostgresql-2b5f049f7c6231cce3d79b8949f7aeee3bb4081a.tar.gz
postgresql-2b5f049f7c6231cce3d79b8949f7aeee3bb4081a.zip
Handle double-quotes correctly in user names in ACL lists.
Christopher Kings-Lynne
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/acl.c48
-rw-r--r--src/bin/pg_dump/dumputils.c13
2 files changed, 40 insertions, 21 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index df87eaa8be5..504e8f55652 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.94 2003/08/04 02:40:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.95 2003/08/14 14:19:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,8 +61,8 @@ static AclMode convert_schema_priv_string(text *priv_type_text);
* RETURNS:
* the string position in 's' that points to the next non-space character
* in 's', after any quotes. Also:
- * - loads the identifier into 'name'. (If no identifier is found, 'name'
- * contains an empty string.) name must be NAMEDATALEN bytes.
+ * - loads the identifier into 'n'. (If no identifier is found, 'n'
+ * contains an empty string.) 'n' must be NAMEDATALEN bytes.
*/
static const char *
getid(const char *s, char *n)
@@ -74,7 +74,7 @@ getid(const char *s, char *n)
while (isspace((unsigned char) *s))
s++;
- /* This test had better match what putid() does, below */
+ /* This code had better match what putid() does, below */
for (;
*s != '\0' &&
(isalnum((unsigned char) *s) ||
@@ -84,18 +84,26 @@ getid(const char *s, char *n)
s++)
{
if (*s == '"')
- in_quotes = !in_quotes;
- else
{
- if (len >= NAMEDATALEN - 1)
- ereport(ERROR,
- (errcode(ERRCODE_NAME_TOO_LONG),
- errmsg("identifier too long"),
- errdetail("Identifier must be less than %d characters.",
- NAMEDATALEN)));
-
- n[len++] = *s;
+ /* safe to look at next char (could be '\0' though) */
+ if (*(s + 1) != '"')
+ {
+ in_quotes = !in_quotes;
+ continue;
+ }
+ /* it's an escaped double quote; skip the escaping char */
+ s++;
}
+
+ /* Add the character to the string */
+ if (len >= NAMEDATALEN - 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_NAME_TOO_LONG),
+ errmsg("identifier too long"),
+ errdetail("Identifier must be less than %d characters.",
+ NAMEDATALEN)));
+
+ n[len++] = *s;
}
n[len] = '\0';
while (isspace((unsigned char) *s))
@@ -104,8 +112,9 @@ getid(const char *s, char *n)
}
/*
- * Write a user or group Name at *p, surrounding it with double quotes if
- * needed. There must be at least NAMEDATALEN+2 bytes available at *p.
+ * Write a user or group Name at *p, adding double quotes if needed.
+ * There must be at least (2*NAMEDATALEN)+2 bytes available at *p.
+ * This needs to be kept in sync with copyAclUserName in pg_dump/dumputils.c
*/
static void
putid(char *p, const char *s)
@@ -125,7 +134,12 @@ putid(char *p, const char *s)
if (!safe)
*p++ = '"';
for (src = s; *src; src++)
+ {
+ /* A double quote character in a username is encoded as "" */
+ if (*src == '"')
+ *p++ = '"';
*p++ = *src;
+ }
if (!safe)
*p++ = '"';
*p = '\0';
@@ -358,7 +372,7 @@ aclitemout(PG_FUNCTION_ARGS)
out = palloc(strlen("group =/") +
2 * N_ACL_RIGHTS +
- 2 * (NAMEDATALEN + 2) +
+ 2 * (2 * NAMEDATALEN + 2) +
1);
p = out;
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 6bd02419205..0878c80a6ff 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.8 2003/08/04 02:40:09 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.9 2003/08/14 14:19:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -557,23 +557,28 @@ static char *
copyAclUserName(PQExpBuffer output, char *input)
{
resetPQExpBuffer(output);
+
while (*input && *input != '=')
{
+ /* If user name isn't quoted, then just add it to the output buffer */
if (*input != '"')
appendPQExpBufferChar(output, *input++);
else
{
+ /* Otherwise, it's a quoted username */
input++;
- while (*input != '"')
+ /* Loop until we come across an unescaped quote */
+ while (!(*input == '"' && *(input + 1) != '"'))
{
if (*input == '\0')
return input; /* really a syntax error... */
/*
- * There is no quoting convention here, thus we can't cope
- * with usernames containing double quotes. Keep this
+ * Quoting convention is to escape " as "". Keep this
* code in sync with putid() in backend's acl.c.
*/
+ if (*input == '"' && *(input + 1) == '"')
+ input++;
appendPQExpBufferChar(output, *input++);
}
input++;