Liu Song’s Projects


~/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 () {