-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 2.6.5
-
Component/s: JavaScript
-
None
-
Fully Compatible
-
ALL
-
Platform 2 04/24/15, Platform 6 07/17/15, Build 7 08/10/15, Build 8 08/31/15
When parsing input from the user to create a Javascript function, the server tests for the presence of the "return" keyword in order to decide whether the input is an expression that needs to have the string "return " prepended to it before being wrapped in a function body. This test is not robust, and incorrectly passes where the string "return" appears with nested quote characters or nested functions.
As a result, Javascript functions created from user-provided expressions may incorrectly return undefined if the function definition contains the "return" keyword.
To reproduce:
> db.eval("5 === '\\' hello '") false // Function returns false: expected. > db.eval("5 === '\\' return '") null // Function returns undefined: unexpected.
As a workaround, explicitly prepend the "return" keyword to the expression:
> db.eval("return 5 === '\\' return '") false // Function returns false: expected.
Original description:
If a $where selector uses the string syntax, I can’t seem to use an anonymous function in the condition. If I do the same query using the function syntax, I get the expected result.
This is a problem for us, because we generate JS that uses lambdas to scope variables, and we use the Java driver, which seems to have no way to use the function syntax rather than the string syntax.
Steps to reproduce:
Using the zips database,db.zips.count({ "$where" : function () { return -1 !== ["AZ", "CO"].indexOf((function (expr) { return (((typeof expr) !== "undefined") && (expr !== null)) ? expr.state : null; })(this)); } })returns 684, as expected, but
db.zips.count({ "$where" : "-1 !== [\"AZ\", \"CO\"].indexOf((function (expr) { return (((typeof expr) !== \"undefined\") && (expr !== null)) ? expr.state : null; })(this))" })(which I hope represents the same query) returns 0.