mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	fix context key validation + add tests
- adds a helper function validateContextKey to keep it DRY
- adds tests ensure key of null "" 1 {} [] [""] [1] [{}] all throw error
			
			
This commit is contained in:
		| @@ -215,6 +215,22 @@ function followParentContext(parent, key) { | ||||
|     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,14 +267,11 @@ function createContext(id,seed,parent) { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Object.defineProperties(obj, { | ||||
|         get: { | ||||
|             value: function(key, storage, callback) { | ||||
|                 var context; | ||||
|  | ||||
|                 if (typeof key !== "string" || !key.length) { | ||||
|                     throw new Error("context get() requires 'key' to be a valid string"); | ||||
|                 } | ||||
|                 if (!callback && typeof storage === 'function') { | ||||
|                     callback = storage; | ||||
|                     storage = undefined; | ||||
| @@ -266,7 +279,14 @@ function createContext(id,seed,parent) { | ||||
|                 if (callback && typeof callback !== 'function'){ | ||||
|                     throw new Error("Callback must be a function"); | ||||
|                 } | ||||
|  | ||||
|                 if (!validateContextKey(key)) { | ||||
|                     var err = Error("Invalid context key"); | ||||
|                     if(callback) { | ||||
|                         return callback(err); | ||||
|                     } else { | ||||
|                         throw err; | ||||
|                     } | ||||
|                 } | ||||
|                 if (!Array.isArray(key)) { | ||||
|                     var keyParts = util.parseContextStore(key); | ||||
|                     key = keyParts.key; | ||||
| @@ -340,10 +360,6 @@ function createContext(id,seed,parent) { | ||||
|         set: { | ||||
|             value: function(key, value, storage, callback) { | ||||
|                 var context; | ||||
|  | ||||
|                 if (typeof key !== "string" || !key.length) { | ||||
|                     throw new Error("context set() requires 'key' to be a valid string"); | ||||
|                 } | ||||
|                 if (!callback && typeof storage === 'function') { | ||||
|                     callback = storage; | ||||
|                     storage = undefined; | ||||
| @@ -351,7 +367,14 @@ function createContext(id,seed,parent) { | ||||
|                 if (callback && typeof callback !== 'function'){ | ||||
|                     throw new Error("Callback must be a function"); | ||||
|                 } | ||||
|  | ||||
|                 if (!validateContextKey(key)) { | ||||
|                     var err = Error("Invalid context key"); | ||||
|                     if(callback) { | ||||
|                         return callback(err); | ||||
|                     } else { | ||||
|                         throw err; | ||||
|                     } | ||||
|                 } | ||||
|                 if (!Array.isArray(key)) { | ||||
|                     var keyParts = util.parseContextStore(key); | ||||
|                     key = keyParts.key; | ||||
|   | ||||
| @@ -1006,7 +1006,155 @@ describe('context', function() { | ||||
|                     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 () { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user