[Geany-Devel] Escaping replacement for placeholder in build commands

Lex Trotman elextr at gmail.com
Sat Dec 15 23:00:19 UTC 2012


>>> I don't think Geany should be interpreting what a user meant by their
>>> command, there are too many edge cases that don't conform to the
>>> "usual" gcc or other rules.  That space may be meant to be there,
>>> Geany has no way of knowing.  Also what if the command has globs in
>>> it, quoting them stops them working :(
> Calm down Lex, I'm not trying to break your whole Geany.  Breathe.
> Inspire; Expire.  Ok ;)

Hi Colomban,

Hehe, sorry, this email arrived just after another project just did
something similar to "sanitise" inputs and broke my setup, making me
very cranky, so I didn't want to have it happen to Geany :)

I agree that the security risk exists, but then it needs a peculiar
filename, the only way to fix that would be to ban any shell
metacharacters in filenames, but some users won't like that.

As for spaces in filenames, see below.

>> I think the idea is to just escape the filenames being replaced into %f
>> et al placeholders, not the whole command en masse. IIRC, the only thing
>> placed into the placeholders is filenames/paths, which should be able to
>> be safely escaped/sanitized without messing up the whole command.
> That's it.  Another example like Matthew's one:  what I want to do is
> only to make sure that e.g. "%f" is never replaced by something that
> will be interpreted as a command.  Those placeholders (%f, %d, %e and
> %p) represent filenames or paths and never user-typed commands, so they
> should never be interpreted as a command.
> For example, the simple command:
>         gcc "%f" -c -o "%e.o"
> Given the current file named:
>         holy "crap.c
> would currently expand to:
>         gcc "holy "crap.c" -c -o "holy "crap.o"
> Which, huh, doesn't mean what you want at all!  The commands will be
> understood as:
> argv[0] = gcc
> argv[1] = holy crap.c -c -o holy
> argv[2] = crap.o
> (if my shell unquoting skills are correct ;))

Understand, I think thats right.

> What the user actually expected was:
> argv[0] = gcc
> argv[1] = holy "crap.c
> argv[2] = -c
> argv[3] = -o
> argv[4] = holy "crap.o
> Obviously, it's not the same :(

Thats obviously whats expected, and yes its not the same.  Although
inconvenient the above erroneous input would of course just give an
error, "holy crap.c -c -o holy" not found.  Well unless it is found :)

> So again, what I want is to make sure the placeholders (%f & co.) are
> properly escaped/quoted/whatever so they never get misinterpreted like
> above.  And as I said, to actually achieve this we have to somewhat
> understand the quoting in the user command because we can't escape the
> same inside or outside shell quotes -- e.g. %f (without quotes) cannot
> be escaped the same way as "%f" (with the quotes).

or %e.* for example?

> But still nothing really clever trying to understand a meaning, just
> knowing the basics like '' and "" are quotes, and \ is an escape so we
> can know how to escape.  Actually the implementation I proposed simply
> closes any open quote before replacing a quoted placeholder, and then
> re-opens it.
> I.e. for the above example, it would replace as:
>         gcc ""'holy "crap.c'"" -c -o ""'holy "crap.o'""
> That's a bit ugly but you don't have to see it, and it's perfectly safe.
>  Also, just to make sure you see what I mean, if the user command didn't
> quote the %f and %e, and the filename simply contained a space:
> command:                gcc %f -c -o %e.o
> filename:               file name.c
> current replacement:    gcc file name.c -c -o file name.o
> fixed replacement:      gcc 'file name.c' -c -o 'file name'.o
> You see? :)

Yeah, thats a normal command, but continuing my example from above,
what do you get if I have

cmd %e.*

because if lets say the filename is xxx.c, if you get

cmd "xxx.*"

then the * won't be treated as a glob since its quoted, so my command
won't work.  It needs to be

cmd "xxx."*

So is g_shell_quote smart enough for all possibilities of shell
metacharacters?  Including the full range of shell patterns, and
backquote command substitution and etc. Then again what if the
filename has a literal * in it, how does g_shell_quote know its
literal or if we meant a glob?

>>>> So, how to fix it?
>>> Don't, its not broke :)
> Yes it is, although it's not really annoying because commands have
> quotes around placeholders and filenames generally don't include "
> literals.  But try compiling a file whose name contains a " literal and
> you'll see it's broken ;)

Heh, ok, but so is using a " literal in a filename in that case :)

> Hope it's clearer now :)

Clearer that its probably wrong, and needs mindreading to be right,
see example above :)


> Cheers,
> Colomban
> _______________________________________________
> Devel mailing list
> Devel at lists.geany.org
> https://lists.geany.org/cgi-bin/mailman/listinfo/devel

More information about the Devel mailing list