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 */
6767static const char *
6868getid (const char * s ,char * n )
@@ -74,7 +74,7 @@ getid(const char *s, char *n)
7474
7575while (isspace ((unsignedchar )* s ))
7676s ++ ;
77- /* Thistest had better match what putid() does, below */
77+ /* Thiscode had better match what putid() does, below */
7878for (;
7979* s != '\0' &&
8080 (isalnum ((unsignedchar )* s )||
@@ -84,18 +84,26 @@ getid(const char *s, char *n)
8484s ++ )
8585{
8686if (* 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}
100108n [len ]= '\0' ;
101109while (isspace ((unsignedchar )* 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 */
110119static void
111120putid (char * p ,const char * s )
@@ -125,7 +134,12 @@ putid(char *p, const char *s)
125134if (!safe )
126135* p ++ = '"' ;
127136for (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+ }
129143if (!safe )
130144* p ++ = '"' ;
131145* p = '\0' ;
@@ -358,7 +372,7 @@ aclitemout(PG_FUNCTION_ARGS)
358372
359373out = palloc (strlen ("group =/" )+
3603742 * N_ACL_RIGHTS +
361- 2 * (NAMEDATALEN + 2 )+
375+ 2 * (2 * NAMEDATALEN + 2 )+
3623761 );
363377
364378p = out ;