From 75e7c0e50da025d9ae1b6968ab21293ba4884be4 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 10 Sep 2018 22:30:51 +0100 Subject: [PATCH] Ensure context.flow/global cannot be deleted or enumerated --- red/runtime/nodes/context/index.js | 181 ++++++++++--------- test/red/runtime/nodes/context/index_spec.js | 15 ++ 2 files changed, 111 insertions(+), 85 deletions(-) diff --git a/red/runtime/nodes/context/index.js b/red/runtime/nodes/context/index.js index c85f18d80..f048947ad 100644 --- a/red/runtime/nodes/context/index.js +++ b/red/runtime/nodes/context/index.js @@ -221,93 +221,100 @@ function createContext(id,seed) { } } } - - obj.get = function(key, storage, callback) { - var context; - if (!storage && !callback) { - context = stores["_"]; - } else { - if (typeof storage === 'function') { - callback = storage; - storage = "_"; - } - if (callback && typeof callback !== 'function'){ - throw new Error("Callback must be a function"); - } - context = getContextStorage(storage); - } - if (callback) { - if (!seed) { - context.get(scope,key,callback); - } else { - context.get(scope,key,function() { - if (arguments[0]) { - callback(arguments[0]); - return; + Object.defineProperties(obj, { + get: { + value: function(key, storage, callback) { + var context; + if (!storage && !callback) { + context = stores["_"]; + } else { + if (typeof storage === 'function') { + callback = storage; + storage = "_"; } - var results = Array.prototype.slice.call(arguments,[1]); - insertSeedValues(key,results); - // Put the err arg back - results.unshift(undefined); - callback.apply(null,results); - }); - } - } else { - // No callback, attempt to do this synchronously - var results = context.get(scope,key); - if (seed) { - if (Array.isArray(key)) { - insertSeedValues(key,results); - } else if (results === undefined){ - results = util.getObjectProperty(seed,key); + if (callback && typeof callback !== 'function'){ + throw new Error("Callback must be a function"); + } + context = getContextStorage(storage); + } + if (callback) { + if (!seed) { + context.get(scope,key,callback); + } else { + context.get(scope,key,function() { + if (arguments[0]) { + callback(arguments[0]); + return; + } + var results = Array.prototype.slice.call(arguments,[1]); + insertSeedValues(key,results); + // Put the err arg back + results.unshift(undefined); + callback.apply(null,results); + }); + } + } else { + // No callback, attempt to do this synchronously + var results = context.get(scope,key); + if (seed) { + if (Array.isArray(key)) { + insertSeedValues(key,results); + } else if (results === undefined){ + results = util.getObjectProperty(seed,key); + } + } + return results; + } + } + }, + set: { + value: function(key, value, storage, callback) { + var context; + if (!storage && !callback) { + context = stores["_"]; + } else { + if (typeof storage === 'function') { + callback = storage; + storage = "_"; + } + if (callback && typeof callback !== 'function') { + throw new Error("Callback must be a function"); + } + context = getContextStorage(storage); + } + context.set(scope, key, value, callback); + } + }, + keys: { + value: function(storage, callback) { + var context; + if (!storage && !callback) { + context = stores["_"]; + } else { + if (typeof storage === 'function') { + callback = storage; + storage = "_"; + } + if (callback && typeof callback !== 'function') { + throw new Error("Callback must be a function"); + } + context = getContextStorage(storage); + } + if (seed) { + if (callback) { + context.keys(scope, function(err,keys) { + callback(err,Array.from(new Set(seedKeys.concat(keys)).keys())); + }); + } else { + var keys = context.keys(scope); + return Array.from(new Set(seedKeys.concat(keys)).keys()) + } + } else { + return context.keys(scope, callback); } } - return results; } - }; - obj.set = function(key, value, storage, callback) { - var context; - if (!storage && !callback) { - context = stores["_"]; - } else { - if (typeof storage === 'function') { - callback = storage; - storage = "_"; - } - if (callback && typeof callback !== 'function') { - throw new Error("Callback must be a function"); - } - context = getContextStorage(storage); - } - context.set(scope, key, value, callback); - }; - obj.keys = function(storage, callback) { - var context; - if (!storage && !callback) { - context = stores["_"]; - } else { - if (typeof storage === 'function') { - callback = storage; - storage = "_"; - } - if (callback && typeof callback !== 'function') { - throw new Error("Callback must be a function"); - } - context = getContextStorage(storage); - } - if (seed) { - if (callback) { - context.keys(scope, function(err,keys) { - callback(err,Array.from(new Set(seedKeys.concat(keys)).keys())); - }); - } else { - var keys = context.keys(scope); - return Array.from(new Set(seedKeys.concat(keys)).keys()) - } - } else { - return context.keys(scope, callback); - } - }; + }); return obj; } @@ -321,9 +328,13 @@ function getContext(localId,flowId) { } var newContext = createContext(contextId); if (flowId) { - newContext.flow = getContext(flowId); + Object.defineProperty(newContext, 'flow', { + value: getContext(flowId) + }); } - newContext.global = contexts['global']; + Object.defineProperty(newContext, 'global', { + value: contexts['global'] + }) contexts[contextId] = newContext; return newContext; } diff --git a/test/red/runtime/nodes/context/index_spec.js b/test/red/runtime/nodes/context/index_spec.js index 6f5a73908..3beb9b201 100644 --- a/test/red/runtime/nodes/context/index_spec.js +++ b/test/red/runtime/nodes/context/index_spec.js @@ -113,6 +113,21 @@ describe('context', function() { context2.global.get("foo").should.equal("test"); }); + it('context.flow/global are not enumerable', function() { + var context1 = Context.get("1","flowA"); + Object.keys(context1).length.should.equal(0); + Object.keys(context1.flow).length.should.equal(0); + Object.keys(context1.global).length.should.equal(0); + }) + + it('context.flow/global cannot be deleted', function() { + var context1 = Context.get("1","flowA"); + delete context1.flow; + should.exist(context1.flow); + delete context1.global; + should.exist(context1.global); + }) + it('deletes context',function() { var context = Context.get("1","flowA"); should.not.exist(context.get("foo"));