On Thu, Nov 28, 2013 at 10:24:19AM +0000, Matthias Lederhofer wrote:
> Just found a problem: sourcing the tmux configuration expands the
> environment variables, too, and I don't see any way that allows
> escaping. That means ':new-window -c "$PWD"' on the prompt works but
> binding the same will resolve $PWD when parsing the config, not when
> pressing the keys. Any recommendations how to solve this?

It should not do variable expansion inside single quotes.
 
> Did one of those "small cosmetic changes" in the last minute and
> missed to remove the & in environ_find(&environ, ...). The attached
> patch fixes that.
> 
> ---
>  cfg.c                |    2 +-
>  cmd-command-prompt.c |    3 ++-
>  cmd-confirm-before.c |    3 ++-
>  cmd-if-shell.c       |    3 ++-
>  cmd-string.c         |   38 +++++++++++++++++++++++---------------
>  control.c            |    3 ++-
>  tmux.h               |    4 ++--
>  window-choose.c      |    3 ++-
>  8 files changed, 36 insertions(+), 23 deletions(-)
> 
> diff --git a/cfg.c b/cfg.c
> index 1153de6..34a49e2 100644
> --- a/cfg.c
> +++ b/cfg.c
> @@ -91,7 +91,7 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
>               }
>  
>               /* Parse and run the command. */
> -             if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) {
> +             if (cmd_string_parse(NULL, buf, &cmdlist, path, n, &cause1) != 
> 0) {
>                       free(copy);
>                       if (cause1 == NULL)
>                               continue;
> diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c
> index 759d578..8c1393c 100644
> --- a/cmd-command-prompt.c
> +++ b/cmd-command-prompt.c
> @@ -172,7 +172,8 @@ cmd_command_prompt_callback(void *data, const char *s)
>               return (1);
>       }
>  
> -     if (cmd_string_parse(new_template, &cmdlist, NULL, 0, &cause) != 0) {
> +     if (cmd_string_parse(&c->session->environ, new_template, &cmdlist,
> +             NULL, 0, &cause) != 0) {
>               if (cause != NULL) {
>                       *cause = toupper((u_char) *cause);
>                       status_message_set(c, "%s", cause);
> diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c
> index 9266721..691810f 100644
> --- a/cmd-confirm-before.c
> +++ b/cmd-confirm-before.c
> @@ -115,7 +115,8 @@ cmd_confirm_before_callback(void *data, const char *s)
>       if (tolower((u_char) s[0]) != 'y' || s[1] != '\0')
>               return (0);
>  
> -     if (cmd_string_parse(cdata->cmd, &cmdlist, NULL, 0, &cause) != 0) {
> +     if (cmd_string_parse(&c->session->environ, cdata->cmd, &cmdlist, NULL,
> +             0, &cause) != 0) {
>               if (cause != NULL) {
>                       cmdq_error(c->cmdq, "%s", cause);
>                       free(cause);
> diff --git a/cmd-if-shell.c b/cmd-if-shell.c
> index 9b6dcf3..e79c0c4 100644
> --- a/cmd-if-shell.c
> +++ b/cmd-if-shell.c
> @@ -123,7 +123,8 @@ cmd_if_shell_callback(struct job *job)
>       if (cmd == NULL)
>               return;
>  
> -     if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
> +     if (cmd_string_parse(&cmdq->client->session->environ, cmd, &cmdlist,
> +             NULL, 0, &cause) != 0) {
>               if (cause != NULL) {
>                       cmdq_error(cmdq, "%s", cause);
>                       free(cause);
> diff --git a/cmd-string.c b/cmd-string.c
> index e793ea0..77dc8af 100644
> --- a/cmd-string.c
> +++ b/cmd-string.c
> @@ -34,9 +34,9 @@
>  int   cmd_string_getc(const char *, size_t *);
>  void  cmd_string_ungetc(size_t *);
>  void  cmd_string_copy(char **, char *, size_t *);
> -char *cmd_string_string(const char *, size_t *, char, int);
> -char *cmd_string_variable(const char *, size_t *);
> -char *cmd_string_expand_tilde(const char *, size_t *);
> +char *cmd_string_string(struct environ *, const char *, size_t *, char, int);
> +char *cmd_string_variable(struct environ *, const char *, size_t *);
> +char *cmd_string_expand_tilde(struct environ *, const char *, size_t *);
>  
>  int
>  cmd_string_getc(const char *s, size_t *p)
> @@ -59,8 +59,8 @@ cmd_string_ungetc(size_t *p)
>   * string, or NULL for empty command.
>   */
>  int
> -cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
> -    u_int line, char **cause)
> +cmd_string_parse(struct environ* environ, const char *s,
> +    struct cmd_list **cmdlist, const char *file, u_int line, char **cause)
>  {
>       size_t          p;
>       int             ch, i, argc, rval;
> @@ -84,17 +84,17 @@ cmd_string_parse(const char *s, struct cmd_list 
> **cmdlist, const char *file,
>               ch = cmd_string_getc(s, &p);
>               switch (ch) {
>               case '\'':
> -                     if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
> +                     if ((t = cmd_string_string(environ, s, &p, '\'', 0)) == 
> NULL)
>                               goto error;
>                       cmd_string_copy(&buf, t, &len);
>                       break;
>               case '"':
> -                     if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
> +                     if ((t = cmd_string_string(environ, s, &p, '"', 1)) == 
> NULL)
>                               goto error;
>                       cmd_string_copy(&buf, t, &len);
>                       break;
>               case '$':
> -                     if ((t = cmd_string_variable(s, &p)) == NULL)
> +                     if ((t = cmd_string_variable(environ, s, &p)) == NULL)
>                               goto error;
>                       cmd_string_copy(&buf, t, &len);
>                       break;
> @@ -140,7 +140,7 @@ cmd_string_parse(const char *s, struct cmd_list 
> **cmdlist, const char *file,
>                       goto out;
>               case '~':
>                       if (buf == NULL) {
> -                             t = cmd_string_expand_tilde(s, &p);
> +                             t = cmd_string_expand_tilde(environ, s, &p);
>                               if (t == NULL)
>                                       goto error;
>                               cmd_string_copy(&buf, t, &len);
> @@ -187,7 +187,7 @@ cmd_string_copy(char **dst, char *src, size_t *len)
>  }
>  
>  char *
> -cmd_string_string(const char *s, size_t *p, char endch, int esc)
> +cmd_string_string(struct environ *environ, const char *s, size_t *p, char 
> endch, int esc)
>  {
>       int     ch;
>       char   *buf, *t;
> @@ -223,7 +223,7 @@ cmd_string_string(const char *s, size_t *p, char endch, 
> int esc)
>               case '$':
>                       if (!esc)
>                               break;
> -                     if ((t = cmd_string_variable(s, p)) == NULL)
> +                     if ((t = cmd_string_variable(environ, s, p)) == NULL)
>                               goto error;
>                       cmd_string_copy(&buf, t, &len);
>                       continue;
> @@ -245,7 +245,7 @@ error:
>  }
>  
>  char *
> -cmd_string_variable(const char *s, size_t *p)
> +cmd_string_variable(struct environ *environ, const char *s, size_t *p)
>  {
>       int                     ch, fch;
>       char                   *buf, *t;
> @@ -302,7 +302,11 @@ cmd_string_variable(const char *s, size_t *p)
>       buf = xrealloc(buf, 1, len + 1);
>       buf[len] = '\0';
>  
> -     envent = environ_find(&global_environ, buf);
> +        envent = NULL;
> +     if (environ)
> +             envent = environ_find(environ, buf);
> +     if (envent == NULL)
> +             envent = environ_find(&global_environ, buf);
>       free(buf);
>       if (envent == NULL)
>               return (xstrdup(""));
> @@ -314,7 +318,7 @@ error:
>  }
>  
>  char *
> -cmd_string_expand_tilde(const char *s, size_t *p)
> +cmd_string_expand_tilde(struct environ *environ, const char *s, size_t *p)
>  {
>       struct passwd           *pw;
>       struct environ_entry    *envent;
> @@ -325,7 +329,11 @@ cmd_string_expand_tilde(const char *s, size_t *p)
>  
>       last = cmd_string_getc(s, p);
>       if (last == EOF || last == '/' || last == ' '|| last == '\t') {
> -             envent = environ_find(&global_environ, "HOME");
> +             envent = NULL;
> +             if (environ)
> +                     envent = environ_find(environ, "HOME");
> +             if (envent == NULL)
> +                     envent = environ_find(&global_environ, "HOME");
>               if (envent != NULL && *envent->value != '\0')
>                       home = envent->value;
>               else if ((pw = getpwuid(getuid())) != NULL)
> diff --git a/control.c b/control.c
> index 52fdb52..4b5df7b 100644
> --- a/control.c
> +++ b/control.c
> @@ -69,7 +69,8 @@ control_callback(struct client *c, int closed, unused void 
> *data)
>                       break;
>               }
>  
> -             if (cmd_string_parse(line, &cmdlist, NULL, 0, &cause) != 0) {
> +             if (cmd_string_parse(&c->session->environ, line, &cmdlist,
> +                     NULL, 0, &cause) != 0) {
>                       c->cmdq->time = time(NULL);
>                       c->cmdq->number++;
>  
> diff --git a/tmux.h b/tmux.h
> index 84ad164..deff813 100644
> --- a/tmux.h
> +++ b/tmux.h
> @@ -1841,8 +1841,8 @@ int              cmdq_continue(struct cmd_q *);
>  void          cmdq_flush(struct cmd_q *);
>  
>  /* cmd-string.c */
> -int  cmd_string_parse(const char *, struct cmd_list **, const char *,
> -         u_int, char **);
> +int  cmd_string_parse(struct environ *, const char *, struct cmd_list **,
> +         const char *, u_int, char **);
>  
>  /* client.c */
>  int  client_main(int, char **, int);
> diff --git a/window-choose.c b/window-choose.c
> index 572581a..bc10b7e 100644
> --- a/window-choose.c
> +++ b/window-choose.c
> @@ -228,7 +228,8 @@ window_choose_data_run(struct window_choose_data *cdata)
>       if (cdata->command == NULL)
>               return;
>  
> -     if (cmd_string_parse(cdata->command, &cmdlist, NULL, 0, &cause) != 0) {
> +     if (cmd_string_parse(&cdata->start_session->environ, cdata->command,
> +             &cmdlist, NULL, 0, &cause) != 0) {
>               if (cause != NULL) {
>                       *cause = toupper((u_char) *cause);
>                       status_message_set(cdata->start_client, "%s", cause);
> -- 
> 1.7.10.4
> 

------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349351&iu=/4140/ostg.clktrk
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to