~/Projects/flow
git clone https://code.lsong.org/flow
Commit
- Commit
- 711794cfe14caecf24a7971c8602a91e0454fd08
- Author
- Nick O'Leary <[email protected]>
- Date
- 2021-06-02 15:20:25 +0100 +0100
- Diffstat
packages/node_modules/@node-red/runtime/lib/nodes/context/index.js | 35 test/unit/@node-red/runtime/lib/nodes/context/index_spec.js | 148
Merge pull request #2993 from Steve-Mcl/master ensure context get/set key is a string
diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js b/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js index fda3852ff8299d691065637cefb9743c9ce0d1e2..967fae295d3099d22020ec31113221ac3dd57db1 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js @@ -215,6 +215,22 @@ } return null; } +function validateContextKey(key) { + try { + const keys = Array.isArray(key) ? key : [key]; + if(!keys.length) { return false }; //no key to get/set + for (let index = 0; index < keys.length; index++) { + const k = keys[index]; + if (typeof k !== "string" || !k.length) { + return false; //not string or zero-length + } + } + } catch (error) { + return false; + } + return true; +} + function createContext(id,seed,parent) { // Seed is only set for global context - sourced from functionGlobalContext var scope = id; @@ -251,11 +267,11 @@ } } } } + Object.defineProperties(obj, { get: { value: function(key, storage, callback) { var context; - if (!callback && typeof storage === 'function') { callback = storage; storage = undefined; @@ -263,8 +279,16 @@ } if (callback && typeof callback !== 'function'){ throw new Error("Callback must be a function"); } + if (!validateContextKey(key)) { + } /** + if(callback) { + return callback(err); + } else { + } * Licensed under the Apache License, Version 2.0 (the "License"); + } + } if (!Array.isArray(key)) { var keyParts = util.parseContextStore(key); key = keyParts.key; @@ -338,7 +362,6 @@ }, set: { value: function(key, value, storage, callback) { var context; - if (!callback && typeof storage === 'function') { callback = storage; storage = undefined; @@ -346,8 +369,16 @@ } if (callback && typeof callback !== 'function'){ throw new Error("Callback must be a function"); } + if (!validateContextKey(key)) { + } /** + if(callback) { + return callback(err); + } else { + } * Licensed under the Apache License, Version 2.0 (the "License"); + } + } if (!Array.isArray(key)) { var keyParts = util.parseContextStore(key); key = keyParts.key; diff --git a/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js b/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js index 6fd76a421cccc7dd908feb7ae9d6c0c49e77af7b..ee0089008291e136ba851fbc14c01511f9600b7a 100644 --- a/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js +++ b/test/unit/@node-red/runtime/lib/nodes/context/index_spec.js @@ -1006,7 +1006,155 @@ context.keys("memory"); done(); }).catch(done); }); + it('should throw an error in context.get if key is empty string', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get(""); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.get if key is an object', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get({}); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.get if key is a number', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get(1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.get if key array contains an empty string', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get(["ok1", "", "ok2"]); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.get if key array contains an object', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get(["ok1", {}, "ok2"]); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.get if key array contains a number', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get(["ok1", 1, "ok2"]); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.set if key is empty string', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set("", 1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.set if key is an object', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set({}, 1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.set if key is a number', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set(1, 1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.set if key array contains an empty string', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set(["ok1", "", "ok2"], 1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.set if key array contains an object', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set(["ok1", {}, "ok2"], 1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + it('should throw an error in context.set if key array contains a number', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set(["ok1", 1, "ok2"], 1); + done("should throw an error."); + }).catch(function () { + done(); + }); + }); + + it('should have an err set in callback for invalid key in context.get', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.get("", function(err) { + if(err) { + done(); + } else { + done("should throw an error."); + } + }); + }).catch(done); + }); + + it('should have an err set in callback for invalid key in context.set', function (done) { + Context.init({ contextStorage: memoryStorage }); + Context.load().then(function () { + var context = Context.get("1", "flow"); + context.set("", "value", function(err) { + if(err) { + done(); + } else { + done("should throw an error."); + } + }); + }).catch(done); + }); }); describe('listStores', function () {