[racket] Environment variables in paths

From: Eli Barzilay (eli at barzilay.org)
Date: Sun Sep 30 01:03:51 EDT 2012

Two days ago, Nick Shelley wrote:
> I can't seem to find a path function that deals with environment
> variables. Is there some variant of cleanse-path that resolves
> environment variables first?
> Concretely, I have an environment variable $WORKSPACE that tells
> where I'm operating from. The result of (getenv "WORKSPACE") is the
> correct absolute path, but (build-path "$WORKSPACE" ...) doesn't
> resolve the variable, so my filesystem commands are failing.

This kind of expansion is a shell-specific functionality, and it does
vary in the kind of syntax and features that shells have.  Just to
give an obvious example, if you implement some common shell-isms, then
you'd get stuff like:

  (build-path "`rm -rf /`")

as well as a whole bunch of hairy rules.  (See for example the kinds
of expansion that you get with zsh...  It has a very long man page on
just that functionality (man zshexpn).)

Two days ago, Nick Shelley wrote:
> The paths are command-line arguments and the tool is run in multiple
> places.  When I run it locally I don't use environment variables,
> but it's also used as a script that's run on Jenkins after a project
> builds, and Jenkins defines the workspace variable.

In both cases (command-line and invoked from a shell script), the
shell should be doing the expansion, and Racket shouldn't even see any
command-line flag with $variables in it.  If whatever you're using
works directly without a shell in between, you could explicitly use a
shell.  For example, if

  racket $WORKSPACE

ends up running racket with a command-line argument of "$WORKSPACE"
then this is what happens, and you can replace that with

  /bin/sh racket $WORKSPACE

or something similar.

> > Could you push things through a call-out to 'system' with the
> > 'echo' program?

That would work, but the security implications can be serious.  Even
if it looks like there's no problems, soon enough you end up with some
web page that passes strings to a process and the story ends in a
predictable way...

> I'm just copying a file, so I could use system to copy the file
> instead of Racket's copy-file, and that would take care of the
> environment stuff. That's probably better than my solution.

(And this suffers from the exact same problem.)

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.