Skip to content

Fix NUL character introducing escape secuence for octal values #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

uu1101
Copy link

@uu1101 uu1101 commented May 28, 2013

We now use hex escape to inject the NUL character.

NUL characters start escape sequence for inserting a byte given its octal
value. This caused problems when environment variables had digit values. For
example, if the value of the variable SSH_AGENT_PID is "46", the command
printf "\046" would result, and the output would be &, as 046 is the octal
value for the ampersand character.

We now use hex escape to inject the NUL character.

NUL characters start escape sequence for inserting a byte given its octal
value. This caused problems when environment variables had digit values. For
example, if the value of the variable SSH_AGENT_PID is "46", the command
`printf "\046"` would result, and the output would be `&`, as 046 is the octal
value for the ampersand character.
@purcell
Copy link
Owner

purcell commented May 28, 2013

Ah, thanks for finding this bug!

I'm not sure that hexadecimal escapes are the best solution, since they do not seem to be supported everywhere. The man page for printf (1) on my system says:

ANSI hexadecimal character constants were deliberately not provided.

The escape sequence \000 is the string terminator.  When present in the argument for the b format,
the argument will be truncated at the \000 character.

so it looks like \000 might be a preferable alternative. Does that work for you?

-Steve

@purcell purcell closed this in 2b66512 May 28, 2013
@purcell
Copy link
Owner

purcell commented May 28, 2013

I made a change to use \000 and tested it out successfully on my system. Please let me know if you have any issues. :-)

@uu1101
Copy link
Author

uu1101 commented May 28, 2013

It works as well on mine. Thank you.

@purcell
Copy link
Owner

purcell commented May 28, 2013

Great! That must have been an adventure to debug...

@mjakl
Copy link

mjakl commented Jun 10, 2013

Hi, I've also had some issues regarding the NUL character. It works fine using bash as $SHELL, but I'm using fish on OS X.

The only variant I could make it work was to replace the NUL of exec-path-from-shell-printf with something completely different (like a colon).

Like this:

(defun exec-path-from-shell-printf (str)
  "Return the result of printing STR in the user's shell.

Executes $SHELL as interactive login shell.

STR is inserted literally in a double-quoted argument to printf,
and may therefore contain backslashed escape sequences, but must not
contain the '%' character."
  (with-temp-buffer
    (call-process (getenv "SHELL") nil (current-buffer) nil
                  "--login" "-i" "-c" (concat "printf \"__RESULT:" str "\""))
    (goto-char (point-min))
    (when (re-search-forward "__RESULT:\\(.*\\)" nil t)
      (match-string 1))))

\0 works fine for the string-splitting in the other functions, though.

@purcell
Copy link
Owner

purcell commented Jun 10, 2013

@mjakl Does fish not have a POSIX-compliant printf?

The \\0 escape sequence in the other function should have been \\000 too, and I've just fixed that (8ec1a90), but perhaps fish's printf understands \\0 but not \\000.

Perhaps see if printf "\000" prints out something like 00...?

@mjakl
Copy link

mjakl commented Jun 10, 2013

fish's printf doesn't print 00 etc, but seems to be the problem anyways: replacing the built-in with /usr/bin/printf works with the NULs.

Maybe using /usr/bin/printf (either GNU coreutils or BSD's) would be more platform independent?

@purcell
Copy link
Owner

purcell commented Jun 10, 2013

I'm a bit wary of adopting any approach which looks for binaries in specific places.

The best solution would be to understand what's going on with fish. But in any case I found an issue with my existing code, in that the null character was actually passed to the shell in a double-quoted string, so it was the shell that interpreted it, not printf itself. I've fixed that issue (as of 89aed99), and maybe the fish issue will now have gone away. :-)

@mjakl
Copy link

mjakl commented Jun 10, 2013

Unfortunately not. Let's disect the what's going on:

The printf-command looks like this: "printf '__RESULT\\000%s\\000%s' $PATH $MANPATH"
When I run that in a fish terminal, I get

__RESULT/Users/mjakl/bin/Users/mjakl/binShared__RESULT/usr/local/bin/usr/local/sbin__RESULT/usr/local/share/npm/bin/usr/local/share/python__RESULT/usr/bin/bin__RESULT/usr/sbin/sbin__RESULT/usr/local/Cellar/fishfish/OpenBeta_r2/bin/usr/X11R6/bin__RESULT/usr/local/share/man:/usr/share/man:/usr/local/Cellar/fishfish/OpenBeta_r2/share/man⏎

The same command in bash (or zsh or csh) gives me:

__RESULT\000/Users/mjakl/bin:/Users/mjakl/binShared:/usr/local/bin:/usr/local/sbin:/usr/local/share/npm/bin:/usr/local/share/python:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/Cellar/fishfish/OpenBeta_r2/bin:/usr/X11R6/bin\000/usr/local/share/man:/usr/share/man:/usr/local/Cellar/fishfish/OpenBeta_r2/share/man

Quite a difference. fish outputs the path as a list (not separated by colons), maybe that's the underlying problem?

I suppose there is no easy solution to that.

@purcell
Copy link
Owner

purcell commented Jun 10, 2013

Yes, there's not going to be an easy way to work around that unusual behaviour!

@jhenahan
Copy link

jhenahan commented Oct 2, 2013

I don't know if it's helpful, but I found this gist that works around the path issue with fish.

purcell added a commit that referenced this pull request Oct 2, 2013
…lt-in

The hope is that this might allow fish to work. See #5.
@purcell
Copy link
Owner

purcell commented Oct 2, 2013

@jhenahan I just pushed a change making exec-path-from-shell prefer the system-wide printf binary, which @Mjaki suggested might help. I'd be grateful if one of you would give that a try. :-)

@jhenahan
Copy link

jhenahan commented Oct 2, 2013

It works! Thanks so much!

@purcell
Copy link
Owner

purcell commented Oct 2, 2013

@jhenahan Excellent. Thanks @mjakl for the suggestion, and your patience 4 months ago: sorry I didn't realise at the time that I could easily make this work without requiring printf to be in a specific place.

@mjakl
Copy link

mjakl commented Oct 2, 2013

Thanks, nice to see this fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants