I found that psql will crash if given a PSQLRC value containing a tilde:

        $ PSQLRC="~/x" psql test
        *** glibc detected *** psql: free(): invalid pointer: 
0x00007fffb7c933ec ***

This is on Debian Squeeze 6.0.7.  The fix is to pstrdup() the value
returned by getenv(), so it can be free()'ed later --- you can't free
getenv()-returned values:

       As typically implemented, getenv() returns a pointer to a string
       within the environment list.  The caller must take care not to
       modify this string, since that would change the environment of
       the process.

This bug exists in 9.2 and git head.  I also removed the return value
from expand_tilde() as no caller was using it.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
new file mode 100644
index be5e34a..3dea92c
*** a/src/bin/psql/common.c
--- b/src/bin/psql/common.c
*************** session_username(void)
*** 1645,1655 ****
   * substitute '~' with HOME or '~username' with username's home dir
   *
   */
! char *
  expand_tilde(char **filename)
  {
  	if (!filename || !(*filename))
! 		return NULL;
  
  	/*
  	 * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
--- 1645,1655 ----
   * substitute '~' with HOME or '~username' with username's home dir
   *
   */
! void
  expand_tilde(char **filename)
  {
  	if (!filename || !(*filename))
! 		return;
  
  	/*
  	 * WIN32 doesn't use tilde expansion for file names. Also, it uses tilde
*************** expand_tilde(char **filename)
*** 1697,1701 ****
  	}
  #endif
  
! 	return *filename;
  }
--- 1697,1701 ----
  	}
  #endif
  
! 	return;
  }
diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h
new file mode 100644
index d8bb093..db645da
*** a/src/bin/psql/common.h
--- b/src/bin/psql/common.h
*************** extern bool is_superuser(void);
*** 44,49 ****
  extern bool standard_strings(void);
  extern const char *session_username(void);
  
! extern char *expand_tilde(char **filename);
  
  #endif   /* COMMON_H */
--- 44,49 ----
  extern bool standard_strings(void);
  extern const char *session_username(void);
  
! extern void expand_tilde(char **filename);
  
  #endif   /* COMMON_H */
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
new file mode 100644
index 5cb6b5f..5d7fe6e
*** a/src/bin/psql/startup.c
--- b/src/bin/psql/startup.c
*************** process_psqlrc(char *argv0)
*** 610,616 ****
  	char		rc_file[MAXPGPATH];
  	char		my_exec_path[MAXPGPATH];
  	char		etc_path[MAXPGPATH];
! 	char	   *envrc;
  
  	find_my_exec(argv0, my_exec_path);
  	get_etc_path(my_exec_path, etc_path);
--- 610,616 ----
  	char		rc_file[MAXPGPATH];
  	char		my_exec_path[MAXPGPATH];
  	char		etc_path[MAXPGPATH];
! 	char	   *envrc = getenv("PSQLRC");
  
  	find_my_exec(argv0, my_exec_path);
  	get_etc_path(my_exec_path, etc_path);
*************** process_psqlrc(char *argv0)
*** 618,629 ****
  	snprintf(rc_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
  	process_psqlrc_file(rc_file);
  
- 	envrc = getenv("PSQLRC");
- 
  	if (envrc != NULL && strlen(envrc) > 0)
  	{
! 		expand_tilde(&envrc);
! 		process_psqlrc_file(envrc);
  	}
  	else if (get_home_path(home))
  	{
--- 618,630 ----
  	snprintf(rc_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
  	process_psqlrc_file(rc_file);
  
  	if (envrc != NULL && strlen(envrc) > 0)
  	{
! 		/* might need to free() this */
! 		char *envrc_alloc = pstrdup(envrc);
! 
! 		expand_tilde(&envrc_alloc);
! 		process_psqlrc_file(envrc_alloc);
  	}
  	else if (get_home_path(home))
  	{
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to