mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Handle double-quotes correctly in user names in ACL lists.
Christopher Kings-Lynne
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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:
|
* RETURNS:
|
||||||
* the string position in 's' that points to the next non-space character
|
* the string position in 's' that points to the next non-space character
|
||||||
* in 's', after any quotes. Also:
|
* in 's', after any quotes. Also:
|
||||||
* - loads the identifier into 'name'. (If no identifier is found, 'name'
|
* - loads the identifier into 'n'. (If no identifier is found, 'n'
|
||||||
* contains an empty string.) name must be NAMEDATALEN bytes.
|
* contains an empty string.) 'n' must be NAMEDATALEN bytes.
|
||||||
*/
|
*/
|
||||||
static const char *
|
static const char *
|
||||||
getid(const char *s, char *n)
|
getid(const char *s, char *n)
|
||||||
@ -74,7 +74,7 @@ getid(const char *s, char *n)
|
|||||||
|
|
||||||
while (isspace((unsigned char) *s))
|
while (isspace((unsigned char) *s))
|
||||||
s++;
|
s++;
|
||||||
/* This test had better match what putid() does, below */
|
/* This code had better match what putid() does, below */
|
||||||
for (;
|
for (;
|
||||||
*s != '\0' &&
|
*s != '\0' &&
|
||||||
(isalnum((unsigned char) *s) ||
|
(isalnum((unsigned char) *s) ||
|
||||||
@ -84,18 +84,26 @@ getid(const char *s, char *n)
|
|||||||
s++)
|
s++)
|
||||||
{
|
{
|
||||||
if (*s == '"')
|
if (*s == '"')
|
||||||
in_quotes = !in_quotes;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (len >= NAMEDATALEN - 1)
|
/* safe to look at next char (could be '\0' though) */
|
||||||
ereport(ERROR,
|
if (*(s + 1) != '"')
|
||||||
(errcode(ERRCODE_NAME_TOO_LONG),
|
{
|
||||||
errmsg("identifier too long"),
|
in_quotes = !in_quotes;
|
||||||
errdetail("Identifier must be less than %d characters.",
|
continue;
|
||||||
NAMEDATALEN)));
|
}
|
||||||
|
/* it's an escaped double quote; skip the escaping char */
|
||||||
n[len++] = *s;
|
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';
|
n[len] = '\0';
|
||||||
while (isspace((unsigned char) *s))
|
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
|
* Write a user or group Name at *p, adding double quotes if needed.
|
||||||
* needed. There must be at least NAMEDATALEN+2 bytes available at *p.
|
* 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
|
static void
|
||||||
putid(char *p, const char *s)
|
putid(char *p, const char *s)
|
||||||
@ -125,7 +134,12 @@ putid(char *p, const char *s)
|
|||||||
if (!safe)
|
if (!safe)
|
||||||
*p++ = '"';
|
*p++ = '"';
|
||||||
for (src = s; *src; src++)
|
for (src = s; *src; src++)
|
||||||
|
{
|
||||||
|
/* A double quote character in a username is encoded as "" */
|
||||||
|
if (*src == '"')
|
||||||
|
*p++ = '"';
|
||||||
*p++ = *src;
|
*p++ = *src;
|
||||||
|
}
|
||||||
if (!safe)
|
if (!safe)
|
||||||
*p++ = '"';
|
*p++ = '"';
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
@ -358,7 +372,7 @@ aclitemout(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
out = palloc(strlen("group =/") +
|
out = palloc(strlen("group =/") +
|
||||||
2 * N_ACL_RIGHTS +
|
2 * N_ACL_RIGHTS +
|
||||||
2 * (NAMEDATALEN + 2) +
|
2 * (2 * NAMEDATALEN + 2) +
|
||||||
1);
|
1);
|
||||||
|
|
||||||
p = out;
|
p = out;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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)
|
copyAclUserName(PQExpBuffer output, char *input)
|
||||||
{
|
{
|
||||||
resetPQExpBuffer(output);
|
resetPQExpBuffer(output);
|
||||||
|
|
||||||
while (*input && *input != '=')
|
while (*input && *input != '=')
|
||||||
{
|
{
|
||||||
|
/* If user name isn't quoted, then just add it to the output buffer */
|
||||||
if (*input != '"')
|
if (*input != '"')
|
||||||
appendPQExpBufferChar(output, *input++);
|
appendPQExpBufferChar(output, *input++);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Otherwise, it's a quoted username */
|
||||||
input++;
|
input++;
|
||||||
while (*input != '"')
|
/* Loop until we come across an unescaped quote */
|
||||||
|
while (!(*input == '"' && *(input + 1) != '"'))
|
||||||
{
|
{
|
||||||
if (*input == '\0')
|
if (*input == '\0')
|
||||||
return input; /* really a syntax error... */
|
return input; /* really a syntax error... */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is no quoting convention here, thus we can't cope
|
* Quoting convention is to escape " as "". Keep this
|
||||||
* with usernames containing double quotes. Keep this
|
|
||||||
* code in sync with putid() in backend's acl.c.
|
* code in sync with putid() in backend's acl.c.
|
||||||
*/
|
*/
|
||||||
|
if (*input == '"' && *(input + 1) == '"')
|
||||||
|
input++;
|
||||||
appendPQExpBufferChar(output, *input++);
|
appendPQExpBufferChar(output, *input++);
|
||||||
}
|
}
|
||||||
input++;
|
input++;
|
||||||
|
Reference in New Issue
Block a user