ソースを参照

Switched jsonpath library to jsonpath-plus. Fixes #1318

n1474335 2 年 前
コミット
1dd1b839b8
4 ファイル変更57 行追加148 行削除
  1. 10 125
      package-lock.json
  2. 1 1
      package.json
  3. 21 12
      src/core/operations/JPathExpression.mjs
  4. 25 10
      tests/operations/tests/Code.mjs

+ 10 - 125
package-lock.json

@@ -46,7 +46,7 @@
         "js-sha3": "^0.8.0",
         "jsesc": "^3.0.2",
         "json5": "^2.2.1",
-        "jsonpath": "^1.1.1",
+        "jsonpath-plus": "^7.2.0",
         "jsonwebtoken": "^8.5.1",
         "jsqr": "^1.4.0",
         "jsrsasign": "^10.5.23",
@@ -9498,26 +9498,12 @@
         "node": ">=6"
       }
     },
-    "node_modules/jsonpath": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz",
-      "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==",
-      "dependencies": {
-        "esprima": "1.2.2",
-        "static-eval": "2.0.2",
-        "underscore": "1.12.1"
-      }
-    },
-    "node_modules/jsonpath/node_modules/esprima": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz",
-      "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs=",
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
-      },
+    "node_modules/jsonpath-plus": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz",
+      "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==",
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">=12.0.0"
       }
     },
     "node_modules/jsonwebtoken": {
@@ -14055,52 +14041,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/static-eval": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz",
-      "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==",
-      "dependencies": {
-        "escodegen": "^1.8.1"
-      }
-    },
-    "node_modules/static-eval/node_modules/escodegen": {
-      "version": "1.14.3",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
-      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
-      "dependencies": {
-        "esprima": "^4.0.1",
-        "estraverse": "^4.2.0",
-        "esutils": "^2.0.2",
-        "optionator": "^0.8.1"
-      },
-      "bin": {
-        "escodegen": "bin/escodegen.js",
-        "esgenerate": "bin/esgenerate.js"
-      },
-      "engines": {
-        "node": ">=4.0"
-      },
-      "optionalDependencies": {
-        "source-map": "~0.6.1"
-      }
-    },
-    "node_modules/static-eval/node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/static-eval/node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/statuses": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
@@ -14767,11 +14707,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/underscore": {
-      "version": "1.12.1",
-      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz",
-      "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw=="
-    },
     "node_modules/underscore.string": {
       "version": "3.3.6",
       "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz",
@@ -23025,22 +22960,10 @@
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
       "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA=="
     },
-    "jsonpath": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz",
-      "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==",
-      "requires": {
-        "esprima": "1.2.2",
-        "static-eval": "2.0.2",
-        "underscore": "1.12.1"
-      },
-      "dependencies": {
-        "esprima": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz",
-          "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs="
-        }
-      }
+    "jsonpath-plus": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz",
+      "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA=="
     },
     "jsonwebtoken": {
       "version": "8.5.1",
@@ -26583,39 +26506,6 @@
         }
       }
     },
-    "static-eval": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz",
-      "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==",
-      "requires": {
-        "escodegen": "^1.8.1"
-      },
-      "dependencies": {
-        "escodegen": {
-          "version": "1.14.3",
-          "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
-          "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
-          "requires": {
-            "esprima": "^4.0.1",
-            "estraverse": "^4.2.0",
-            "esutils": "^2.0.2",
-            "optionator": "^0.8.1",
-            "source-map": "~0.6.1"
-          }
-        },
-        "estraverse": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-          "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "optional": true
-        }
-      }
-    },
     "statuses": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
@@ -27126,11 +27016,6 @@
       "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
       "dev": true
     },
-    "underscore": {
-      "version": "1.12.1",
-      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz",
-      "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw=="
-    },
     "underscore.string": {
       "version": "3.3.6",
       "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz",

+ 1 - 1
package.json

@@ -123,7 +123,7 @@
     "js-sha3": "^0.8.0",
     "jsesc": "^3.0.2",
     "json5": "^2.2.1",
-    "jsonpath": "^1.1.1",
+    "jsonpath-plus": "^7.2.0",
     "jsonwebtoken": "^8.5.1",
     "jsqr": "^1.4.0",
     "jsrsasign": "^10.5.23",

+ 21 - 12
src/core/operations/JPathExpression.mjs

@@ -4,7 +4,7 @@
  * @license Apache-2.0
  */
 
-import jpath from "jsonpath";
+import {JSONPath} from "jsonpath-plus";
 import Operation from "../Operation.mjs";
 import OperationError from "../errors/OperationError.mjs";
 
@@ -27,14 +27,20 @@ class JPathExpression extends Operation {
         this.outputType = "string";
         this.args = [
             {
-                "name": "Query",
-                "type": "string",
-                "value": ""
+                name: "Query",
+                type: "string",
+                value: ""
             },
             {
-                "name": "Result delimiter",
-                "type": "binaryShortString",
-                "value": "\\n"
+                name: "Result delimiter",
+                type: "binaryShortString",
+                value: "\\n"
+            },
+            {
+                name: "Prevent eval",
+                type: "boolean",
+                value: true,
+                description: "Evaluated expressions are disabled by default for security reasons"
             }
         ];
     }
@@ -45,18 +51,21 @@ class JPathExpression extends Operation {
      * @returns {string}
      */
     run(input, args) {
-        const [query, delimiter] = args;
-        let results,
-            obj;
+        const [query, delimiter, preventEval] = args;
+        let results, jsonObj;
 
         try {
-            obj = JSON.parse(input);
+            jsonObj = JSON.parse(input);
         } catch (err) {
             throw new OperationError(`Invalid input JSON: ${err.message}`);
         }
 
         try {
-            results = jpath.query(obj, query);
+            results = JSONPath({
+                path: query,
+                json: jsonObj,
+                preventEval: preventEval
+            });
         } catch (err) {
             throw new OperationError(`Invalid JPath expression: ${err.message}`);
         }

+ 25 - 10
tests/operations/tests/Code.mjs

@@ -185,11 +185,11 @@ TestRegister.addTests([
     {
         name: "JPath Expression: Empty expression",
         input: JSON.stringify(JSON_TEST_DATA),
-        expectedOutput: "Invalid JPath expression: we need a path",
+        expectedOutput: "",
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["", "\n"]
+                "args": ["", "\n", true]
             }
         ],
     },
@@ -205,7 +205,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$.store.book[*].author", "\n"]
+                "args": ["$.store.book[*].author", "\n", true]
             }
         ],
     },
@@ -223,7 +223,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$..title", "\n"]
+                "args": ["$..title", "\n", true]
             }
         ],
     },
@@ -238,7 +238,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$.store.*", "\n"]
+                "args": ["$.store.*", "\n", true]
             }
         ],
     },
@@ -249,7 +249,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$..book[-1:]", "\n"]
+                "args": ["$..book[-1:]", "\n", true]
             }
         ],
     },
@@ -263,7 +263,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$..book[:2]", "\n"]
+                "args": ["$..book[:2]", "\n", true]
             }
         ],
     },
@@ -277,7 +277,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$..book[?(@.isbn)]", "\n"]
+                "args": ["$..book[?(@.isbn)]", "\n", false]
             }
         ],
     },
@@ -292,7 +292,7 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$..book[?(@.price<30 && @.category==\"fiction\")]", "\n"]
+                "args": ["$..book[?(@.price<30 && @.category==\"fiction\")]", "\n", false]
             }
         ],
     },
@@ -306,9 +306,24 @@ TestRegister.addTests([
         recipeConfig: [
             {
                 "op": "JPath expression",
-                "args": ["$..book[?(@.price<10)]", "\n"]
+                "args": ["$..book[?(@.price<10)]", "\n", false]
+            }
+        ],
+    },
+    {
+        name: "JPath Expression: Script-based expression",
+        input: "[{}]",
+        recipeConfig: [
+            {
+                "op": "JPath expression",
+                "args": [
+                    "$..[?(({__proto__:[].constructor}).constructor(\"self.postMessage({action:'bakeComplete',data:{bakeId:1,dish:{type:1,value:''},duration:1,error:false,id:undefined,inputNum:2,progress:1,result:'<iframe/onload=debugger>',type: 'html'}});\")();)]",
+                    "\n",
+                    true
+                ]
             }
         ],
+        expectedOutput: "Invalid JPath expression: Eval [?(expr)] prevented in JSONPath expression."
     },
     {
         name: "CSS selector",