This makes me nervous. Really we would like to pass _all_ properties to Ant using `-propertyfile`, as this avoids operating-system-dependent problems with process execution, and also keeps values out of the build log (and `ps www` list) which might be sensitive from a security standpoint.

The real question is what people expect to happen when a “shell” variable is encoded in the job’s configured Ant properties. I would argue that the above logic is wrong; you do not want the OS shell interpreting environment variables like this on its own. In particular, using `%VAR%` is wrong because this will only work if the job happens to be run on a Windows node, whereas Ant builds are otherwise usually portable. (It is not clear that your test case would even pass on Windows.)

I think what is wanted is `EnvVars.expand` (or `Util.replaceMacro`) with the build’s other variables. This would give a consistent variable expansion semantics that matches what other Jenkins tasks does, that is independent of the operating system on which this build happens to be run, and that would cleanly handle a variety of special characters (and Unicode).