-
-
Notifications
You must be signed in to change notification settings - Fork 481
Description
While developing a ctags parser for XSLT, I uncovered a subtle issue with s:EscapeCtagsCmd() in tagbar that causes problems on windows (cmd.exe) machines when the a:ctags_bin is a batch file that depends on evaluation of %~dp0 in order to run correctly.
See https://gist.github.com/darcyparker/5267063 that illustrates the problem with %~dp0. Using %~dp0 is a common practice in windows because batch files are written as wrappers and the batch file needs to know where to find other files required by the script.
I traced the problem to this line.
On Windows, I don't think shellescape() should be used on
shellescape(a:ctags_bin) when the command is just a single file name and not the full path. It doesn't hurt to have it for unix-y shells, but I don't think it is needed because there aren't really any commands that have spaces or need escaping. Only the additional arguments need to be escaped. So I think it is safe to just eliminate the shellescape() on the command. (not the args)
It is good to run shellescape() on each argument (but not the whole set of arguments at once, but each argument individually). See the findings in this pull request accepted for syntasic.
Side note: Currently ctagsargs in g:tagbar_type_xxx is a string of all arguments to be passed. I haven't seen a particular problem with it today, but based on findings in syntastic pull request mentioned above, I think it would be more robust if an array of each argument was passed. Then shellescape() should be run on each argument and the results joined rather than a single shellescape() on the full argument string. Maybe this would also eliminate the need for the if block that follows about the 'stupid cmd.exe quoting'?
So based on the findings in my gist mentioned above, it seems like it is not a good practice to escape the command or 0th argument.
Does this make sense?
I can submit a pull request, but wanted to get your input first. Maybe just the issue with not escaping the command name (0th argument), should be addressed first. And the suggestion to escape each of the passed arguments separately should be handled in the future. (A solution that supports the existing data structure that uses a single string for ctagsargs and the proposed array for ctagsargs is probably something that would be better for you to think about.)
With regards to a potential pull request: It won't take long because I can confirm that let ctags_cmd = a:ctags_bin . ' ' . a:args . ' ' . fname works correctly on windows based on my testing of my xsltctags tool that uses a .bat file without the workaround mentioned in my gist. But I have not added code to test if a:ctags_bin contains things that need to be escaped. (For example a full path that includes a space.)