leoliu / ggtags

Emacs frontend to GNU Global source code tagging system.

Home Page:http://elpa.gnu.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Search terms are not adequately escaped

jonathanj opened this issue · comments

M-x ggtags-find-tag-dwim ->Decimal produces the following error:

global -v --result=grep --color=always --path-style=shorter -\>Decimal
global: invalid option -- '>'

M-x ggtags-find-tag-dwim *assert* produces a slightly different error, although still a result of inadequate escaping:

global -v --result=grep --color=always --path-style=shorter \*assert\*
global: invalid regular expression.

It's fairly common in Clojure (and maybe other lisps?) to name functions ->foo (with the convention implying "convert anything to foo") or -bar (usually implying private) or *baz* (usually implying dynamic.)

Looks like we need the following patch:

diff --git a/ggtags.el b/ggtags.el
index b3ab1f61..c0a9a9ee 100644
--- a/ggtags.el
+++ b/ggtags.el
@@ -1022,7 +1022,7 @@ (defun ggtags-find-tag-dwim (name &optional what)
                 (funcall (if (ggtags-sort-by-nearness-p)
                              #'file-relative-name #'ggtags-project-relative-file)
                          buffer-file-name)))
-       (shell-quote-argument name)))))
+       "--" (shell-quote-argument name)))))
 
 (defun ggtags-find-tag-mouse (event)
   (interactive "e")
@@ -1034,7 +1034,7 @@ (defun ggtags-find-tag-mouse (event)
 ;; Another option for `M-.'.
 (defun ggtags-find-definition (name)
   (interactive (list (ggtags-read-tag 'definition current-prefix-arg)))
-  (ggtags-find-tag 'definition (shell-quote-argument name)))
+  (ggtags-find-tag 'definition "--" (shell-quote-argument name)))
 
 (defun ggtags-setup-libpath-search (type name)
   (pcase (and ggtags-global-search-libpath-for-reference
@@ -1056,13 +1056,13 @@ (defun ggtags-setup-libpath-search (type name)
 (defun ggtags-find-reference (name)
   (interactive (list (ggtags-read-tag 'reference current-prefix-arg)))
   (ggtags-setup-libpath-search 'reference name)
-  (ggtags-find-tag 'reference (shell-quote-argument name)))
+  (ggtags-find-tag 'reference "--" (shell-quote-argument name)))
 
 (defun ggtags-find-other-symbol (name)
   "Find tag NAME that is a reference without a definition."
   (interactive (list (ggtags-read-tag 'symbol current-prefix-arg)))
   (ggtags-setup-libpath-search 'symbol name)
-  (ggtags-find-tag 'symbol (shell-quote-argument name)))
+  (ggtags-find-tag 'symbol "--" (shell-quote-argument name)))
 
 (defun ggtags-quote-pattern (pattern)
   (prin1-to-string (substring-no-properties pattern)))

That looks like it'll work. Thanks for the lightning quick response!

Thanks.

Hmm, something I actually forgot to consider was my secondary issue with \*foo\*. The issue here is that this is an invalid regular expression not that it's being accidentally parsed as an option. Should I file another issue for this?

Do you have a proposal how to fix the second issue? I experimented with it and found that it seemed to treat any string with some chars (e.g. *) in it as regexp.

There is a --literal option to GNU Global that treats the search term as literal text instead of a regular expression. I think for the case where the symbol name is identified from the point it would make sense to pass --literal; however when the user is prompted for a symbol name it may be expected that a regular expression can be given, at least that's the current behaviour and it may be undesirable to change that.

I would be happy with an option to turn --literal on and off globally.

I did note --literal but it seemed to do something else. Could you try also to see if it does what you need?

I tried it before writing my comment and it produced the expected result, namely global --literal -sx \*foo\* produced a result for my variable named *foo* instead of an error about an invalid regular expression. I also tried some names without special characters in them and they still work.

Did you see different behaviour?

I did see a different result. Will look into it in more details tomorrow. Thanks.

--literal makes no difference in the following example:

global --literal -v --result=grep --color=always --path-style=shorter --from-here=77:emulator/beam/erl_process.c -- \*ok\*

global: regular expression is not allowed with the --from-here option.

Reading the source code for GNU Global, this looks like a bug to me. --literal should imply that there is in fact no regular expression.

However it's worth noting that adding --literal is not a regression here because at the moment trying to find a symbol named *ok* will fail in exactly the same way. In the worst case the behaviour remains the same, in the best case GNU Global fixes the interaction between --literal and --from-here and it works as intended with the --literal option.

I'll send a mail to the GNU Global bug report list.

@leoliu I reported the bug to the GNU Global mailing list with a patch, which was accepted: http://lists.gnu.org/archive/html/global-commit/2017-09/msg00003.html

I don't think this has made it into a stable release yet though.