8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -61,8 +61,8 @@ static AclMode convert_schema_priv_string(text *priv_type_text);
61
61
* RETURNS:
62
62
* the string position in 's' that points to the next non-space character
63
63
* 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.
66
66
*/
67
67
static const char *
68
68
getid (const char * s , char * n )
@@ -74,7 +74,7 @@ getid(const char *s, char *n)
74
74
75
75
while (isspace ((unsigned char ) * s ))
76
76
s ++ ;
77
- /* This test had better match what putid() does, below */
77
+ /* This code had better match what putid() does, below */
78
78
for (;
79
79
* s != '\0' &&
80
80
(isalnum ((unsigned char ) * s ) ||
@@ -84,18 +84,26 @@ getid(const char *s, char *n)
84
84
s ++ )
85
85
{
86
86
if (* s == '"' )
87
- in_quotes = !in_quotes ;
88
- else
89
87
{
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 ++ ;
98
96
}
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 ;
99
107
}
100
108
n [len ] = '\0' ;
101
109
while (isspace ((unsigned char ) * s ))
@@ -104,8 +112,9 @@ getid(const char *s, char *n)
104
112
}
105
113
106
114
/*
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
109
118
*/
110
119
static void
111
120
putid (char * p , const char * s )
@@ -125,7 +134,12 @@ putid(char *p, const char *s)
125
134
if (!safe )
126
135
* p ++ = '"' ;
127
136
for (src = s ; * src ; src ++ )
137
+ {
138
+ /* A double quote character in a username is encoded as "" */
139
+ if (* src == '"' )
140
+ * p ++ = '"' ;
128
141
* p ++ = * src ;
142
+ }
129
143
if (!safe )
130
144
* p ++ = '"' ;
131
145
* p = '\0' ;
@@ -358,7 +372,7 @@ aclitemout(PG_FUNCTION_ARGS)
358
372
359
373
out = palloc (strlen ("group =/" ) +
360
374
2 * N_ACL_RIGHTS +
361
- 2 * (NAMEDATALEN + 2 ) +
375
+ 2 * (2 * NAMEDATALEN + 2 ) +
362
376
1 );
363
377
364
378
p = out ;
0 commit comments