@ -10,7 +10,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $ PostgreSQL : pgsql / src / backend / libpq / hba . c , v 1.149 .2 .1 2010 / 03 / 03 20 : 31 : 34 tgl Exp $
* $ PostgreSQL : pgsql / src / backend / libpq / hba . c , v 1.149 .2 .2 2010 / 03 / 06 00 : 46 : 13 tgl Exp $
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
@ -102,6 +102,10 @@ pg_isblank(const char c)
* double quotes ( and usually are , in current usage ) .
* double quotes ( and usually are , in current usage ) .
*
*
* The token , if any , is returned at * buf ( a buffer of size bufsz ) .
* The token , if any , is returned at * buf ( a buffer of size bufsz ) .
* Also , we set * initial_quote to indicate whether there was quoting before
* the first character . ( We use that to prevent " @x " from being treated
* as a file inclusion request . Note that @ " x " should be so treated ;
* we want to allow that to support embedded spaces in file paths . )
*
*
* If successful : store null - terminated token at * buf and return TRUE .
* If successful : store null - terminated token at * buf and return TRUE .
* If no more tokens on line : set * buf = ' \0 ' and return FALSE .
* If no more tokens on line : set * buf = ' \0 ' and return FALSE .
@ -114,7 +118,7 @@ pg_isblank(const char c)
* database names specially , by appending a newline to them .
* database names specially , by appending a newline to them .
*/
*/
static bool
static bool
next_token ( FILE * fp , char * buf , int bufsz )
next_token ( FILE * fp , char * buf , int bufsz , bool * initial_quote )
{
{
int c ;
int c ;
char * start_buf = buf ;
char * start_buf = buf ;
@ -123,8 +127,11 @@ next_token(FILE *fp, char *buf, int bufsz)
bool was_quote = false ;
bool was_quote = false ;
bool saw_quote = false ;
bool saw_quote = false ;
/* end_buf reserves two bytes to ensure we can append \n and \0 */
Assert ( end_buf > start_buf ) ;
Assert ( end_buf > start_buf ) ;
* initial_quote = false ;
/* Move over initial whitespace and commas */
/* Move over initial whitespace and commas */
while ( ( c = getc ( fp ) ) ! = EOF & & ( pg_isblank ( c ) | | c = = ' , ' ) )
while ( ( c = getc ( fp ) ) ! = EOF & & ( pg_isblank ( c ) | | c = = ' , ' ) )
;
;
@ -183,6 +190,8 @@ next_token(FILE *fp, char *buf, int bufsz)
{
{
in_quote = ! in_quote ;
in_quote = ! in_quote ;
saw_quote = true ;
saw_quote = true ;
if ( buf = = start_buf )
* initial_quote = true ;
}
}
c = getc ( fp ) ;
c = getc ( fp ) ;
@ -225,12 +234,13 @@ next_token_expand(const char *filename, FILE *file)
char * comma_str = pstrdup ( " " ) ;
char * comma_str = pstrdup ( " " ) ;
bool got_something = false ;
bool got_something = false ;
bool trailing_comma ;
bool trailing_comma ;
bool initial_quote ;
char * incbuf ;
char * incbuf ;
int needed ;
int needed ;
do
do
{
{
if ( ! next_token ( file , buf , sizeof ( buf ) ) )
if ( ! next_token ( file , buf , sizeof ( buf ) , & initial_quote ) )
break ;
break ;
got_something = true ;
got_something = true ;
@ -244,7 +254,7 @@ next_token_expand(const char *filename, FILE *file)
trailing_comma = false ;
trailing_comma = false ;
/* Is this referencing a file? */
/* Is this referencing a file? */
if ( buf [ 0 ] = = ' @ ' )
if ( ! initial_quote & & buf [ 0 ] = = ' @ ' & & buf [ 1 ] ! = ' \0 ' )
incbuf = tokenize_inc_file ( filename , buf + 1 ) ;
incbuf = tokenize_inc_file ( filename , buf + 1 ) ;
else
else
incbuf = pstrdup ( buf ) ;
incbuf = pstrdup ( buf ) ;
@ -1013,32 +1023,33 @@ read_pg_database_line(FILE *fp, char *dbname, Oid *dboid,
TransactionId * dbvacuumxid )
TransactionId * dbvacuumxid )
{
{
char buf [ MAX_TOKEN ] ;
char buf [ MAX_TOKEN ] ;
bool initial_quote ;
if ( feof ( fp ) )
if ( feof ( fp ) )
return false ;
return false ;
if ( ! next_token ( fp , buf , sizeof ( buf ) ) )
if ( ! next_token ( fp , buf , sizeof ( buf ) , & initial_quote ) )
return false ;
return false ;
if ( strlen ( buf ) > = NAMEDATALEN )
if ( strlen ( buf ) > = NAMEDATALEN )
elog ( FATAL , " bad data in flat pg_database file " ) ;
elog ( FATAL , " bad data in flat pg_database file " ) ;
strcpy ( dbname , buf ) ;
strcpy ( dbname , buf ) ;
next_token ( fp , buf , sizeof ( buf ) ) ;
next_token ( fp , buf , sizeof ( buf ) , & initial_quote ) ;
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
elog ( FATAL , " bad data in flat pg_database file " ) ;
elog ( FATAL , " bad data in flat pg_database file " ) ;
* dboid = atooid ( buf ) ;
* dboid = atooid ( buf ) ;
next_token ( fp , buf , sizeof ( buf ) ) ;
next_token ( fp , buf , sizeof ( buf ) , & initial_quote ) ;
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
elog ( FATAL , " bad data in flat pg_database file " ) ;
elog ( FATAL , " bad data in flat pg_database file " ) ;
* dbtablespace = atooid ( buf ) ;
* dbtablespace = atooid ( buf ) ;
next_token ( fp , buf , sizeof ( buf ) ) ;
next_token ( fp , buf , sizeof ( buf ) , & initial_quote ) ;
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
elog ( FATAL , " bad data in flat pg_database file " ) ;
elog ( FATAL , " bad data in flat pg_database file " ) ;
* dbfrozenxid = atoxid ( buf ) ;
* dbfrozenxid = atoxid ( buf ) ;
next_token ( fp , buf , sizeof ( buf ) ) ;
next_token ( fp , buf , sizeof ( buf ) , & initial_quote ) ;
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
if ( ! isdigit ( ( unsigned char ) buf [ 0 ] ) )
elog ( FATAL , " bad data in flat pg_database file " ) ;
elog ( FATAL , " bad data in flat pg_database file " ) ;
* dbvacuumxid = atoxid ( buf ) ;
* dbvacuumxid = atoxid ( buf ) ;
/* expect EOL next */
/* expect EOL next */
if ( next_token ( fp , buf , sizeof ( buf ) ) )
if ( next_token ( fp , buf , sizeof ( buf ) , & initial_quote ) )
elog ( FATAL , " bad data in flat pg_database file " ) ;
elog ( FATAL , " bad data in flat pg_database file " ) ;
return true ;
return true ;
}
}