8000 Handle double-quotes correctly in user names in ACL lists. · dirbacke/postgres@2b5f049 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2b5f049

Browse files
committed
Handle double-quotes correctly in user names in ACL lists.
Christopher Kings-Lynne
1 parent 8e97f45 commit 2b5f049

File tree

2 files changed

+40
-21
lines changed
8000

2 files changed

+40
-21
lines changed

src/backend/utils/adt/acl.c

Lines changed: 31 additions & 17 deletions
< 6D4E td data-grid-cell-id="diff-2f76603fca966babffafc4a8f9ae3443f13cbcb43c871c02d9680bcd3a529e75-129-143-1" data-selected="false" role="gridcell" style="background-color:var(--bgColor-default);text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative diff-line-number-neutral left-side">143
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.94 2003/08/04 02:40:04 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.95 2003/08/14 14:19:07 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -61,8 +61,8 @@ static AclMode convert_schema_priv_string(text *priv_type_text);
6161
* RETURNS:
6262
* the string position in 's' that points to the next non-space character
6363
* in 's', after any quotes. Also:
64-
* - loads the identifier into 'name'. (If no identifier is found, 'name'
65-
* contains an empty string.) name must be NAMEDATALEN bytes.
64+
* - loads the identifier into 'n'. (If no identifier is found, 'n'
65+
* contains an empty string.) 'n' must be NAMEDATALEN bytes.
6666
*/
6767
static const char *
6868
getid(const char *s, char *n)
@@ -74,7 +74,7 @@ getid(const char *s, char *n)
7474

7575
while (isspace((unsigned char) *s))
7676
s++;
77-
/* This test had better match what putid() does, below */
77+
/* This code had better match what putid() does, below */
7878
for (;
7979
*s != '\0' &&
8080
(isalnum((unsigned char) *s) ||
@@ -84,18 +84,26 @@ getid(const char *s, char *n)
8484
s++)
8585
{
8686
if (*s == '"')
87-
in_quotes = !in_quotes;
88-
else
8987
{
90-
if (len >= NAMEDATALEN - 1)
91-
ereport(ERROR,
92-
(errcode(ERRCODE_NAME_TOO_LONG),
93-
errmsg("identifier too long"),
94-
errdetail("Identifier must be less than %d characters.",
95-
NAMEDATALEN)));
96-
97-
n[len++] = *s;
88+
/* safe to look at next char (could be '\0' though) */
89+
if (*(s + 1) != '"')
90+
{
91+
in_quotes = !in_quotes;
92+
continue;
93+
}
94+
/* it's an escaped double quote; skip the escaping char */
95+
s++;
9896
}
97+
98+
/* Add the character to the string */
99+
if (len >= NAMEDATALEN - 1)
100+
ereport(ERROR,
101+
(errcode(ERRCODE_NAME_TOO_LONG),
102+
errmsg("identifier too long"),
103+
errdetail("Identifier must be less than %d characters.",
104+
NAMEDATALEN)));
105+
106+
n[len++] = *s;
99107
}
100108
n[len] = '\0';
101109
while (isspace((unsigned char) *s))
@@ -104,8 +112,9 @@ getid(const char *s, char *n)
104112
}
105113

106114
/*
107-
* Write a user or group Name at *p, surrounding it with double quotes if
108-
* needed. There must be at least NAMEDATALEN+2 bytes available at *p.
115+
* Write a user or group Name at *p, adding double quotes if needed.
116+
* There must be at least (2*NAMEDATALEN)+2 bytes available at *p.
117+
* This needs to be kept in sync with copyAclUserName in pg_dump/dumputils.c
109118
*/
110119
static void
111120
putid(char *p, const char *s)
@@ -125,7 +134,12 @@ putid(char *p, const char *s)
125134
if (!safe)
126135
*p++ = '"';
127136
for (src = s; *src; src++)
137+
{
138+
/* A double quote character in a username is encoded as "" */
139+
if (*src == '"')
140+
*p++ = '"';
128141
*p++ = *src;
142+
}
129
if (!safe)
130144
*p++ = '"';
131145
*p = '\0';
@@ -358,7 +372,7 @@ aclitemout(PG_FUNCTION_ARGS)
358372

359373
out = palloc(strlen("group =/") +
360374
2 * N_ACL_RIGHTS +
361-
2 * (NAMEDATALEN + 2) +
375+
2 * (2 * NAMEDATALEN + 2) +
362376
1);
363377

364378
p = out;

src/bin/pg_dump/dumputils.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.8 2003/08/04 02:40:09 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.9 2003/08/14 14:19:11 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -557,23 +557,28 @@ static char *
557557
copyAclUserName(PQExpBuffer output, char *input)
558558
{
559559
resetPQExpBuffer(output);
560+
560561
while (*input && *input != '=')
561562
{
563+
/* If user name isn't quoted, then just add it to the output buffer */
562564
if (*input != '"')
563565
appendPQExpBufferChar(output, *input++);
564566
else
565567
{
568+
/* Otherwise, it's a quoted username */
566569
input++;
567-
while (*input != '"')
570+
/* Loop until we come across an unescaped quote */
571+
while (!(*input == '"' && *(input + 1) != '"'))
568572
{
569573
if (*input == '\0')
570574
return input; /* really a syntax error... */
571575

572576
/*
573-
* There is no quoting convention here, thus we can't cope
574-
* with usernames containing double quotes. Keep this
577+
* Quoting convention is to escape " as "". Keep this
575578
* code in sync with putid() in backend's acl.c.
576579
*/
580+
if (*input == '"' && *(input + 1) == '"')
581+
input++;
577582
appendPQExpBufferChar(output, *input++);
578583
}
579584
input++;

0 commit comments

Comments
 (0)
0