The arguments to shellHelper.* functions are passed to scope->exec() as an inline JS string delimited by double quotes on dbshell.cpp:866-867 — but double quotes in the passed arguments are not escaped.
This isn't typically a problem for the existing builtin shellHelper functions (use, set, it, show, and help), because their arguments don't usually include quotes or string literals. However, it's problematic for useful mongorc hacks which take arbitrary JS as args, eg. time and underscore-grab. The effect is usually inexplicable-looking syntax errors when double quotes are used — but not when they are swapped for single quotes (or manually escaped, which looks and feels bizarre):
$ /m/3.2.0-rc2/bin/mongo MongoDB shell version: 3.2.0-rc2 connecting to: test > time sleep(1000) null Duration: 1017 ms > time for (i = 0; i < 100000; i++){} undefined Duration: 39 ms > time for (i = 0; i < 100000; i++){s = "" + i;} 2015-11-16T08:54:08.052+1100 E QUERY [thread1] SyntaxError: missing ) after argument list @(shellhelp2):1:58 > time for (i = 0; i < 100000; i++){s = '' + i;} "99999" Duration: 59 ms > time for (i = 0; i < 100000; i++){s = \"\" + i;} "99999" Duration: 52 ms > use test" + (bar = "foobar") + "foo switched to db testfoobarfoo > bar foobar > bar = 1234 1234 > use test" + bar + "foo switched to db test1234foo
There is an attempt to protect against this on line 856, but it only guards cmd, ie. the first call to scope->exec() on line 859. It also completely prevents the use of shellHelpers where the first word contains a double quote, which is needlessly restrictive — all that should be necessary is to correctly handle double quotes in cmd.
Seems the better approach would be to drop line 856, and instead either (a) use backslash to escape any double quotes in cmd and code, or (b) better yet, directly inject the strings with scope->setString(), and then just reference them when calling shellHelper inside scope->exec().
- is related to
-
SERVER-38338 Add default "mongo" shell helper method to inform user of error
- Closed