From a7ccd2289ebc101b61358e5e1a95730c7443a7ca Mon Sep 17 00:00:00 2001 From: realdennis Date: Mon, 2 Sep 2019 12:12:46 +0800 Subject: [PATCH 1/7] feat. ignoreFunction in options --- index.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 41a8999..e0bf6db 100644 --- a/index.js +++ b/index.js @@ -31,6 +31,22 @@ function escapeUnsafeChars(unsafeChar) { return ESCAPED_CHARS[unsafeChar]; } +function deleteFunctions(obj){ + var functionKeys = [] + for(var key in obj){ + if(typeof obj[key] === 'function'){ + functionKeys.push(key); + } + } + for(var i=0; i typeof obj[key] === "function") + // .forEach(functionKey => { + // delete obj[functionKey]; + // }); +} module.exports = function serialize(obj, options) { options || (options = {}); @@ -49,7 +65,9 @@ module.exports = function serialize(obj, options) { // Returns placeholders for functions and regexps (identified by index) // which are later replaced by their string representation. function replacer(key, value) { - + if(options.ignoreFunction){ + deleteFunctions(value); + } if (!value && value !== undefined) { return value; } @@ -125,6 +143,9 @@ module.exports = function serialize(obj, options) { return serializedFn; } + if( options.ignoreFunction && typeof obj==='function'){ + obj = undefined; + } // Protects against `JSON.stringify()` returning `undefined`, by serializing // to the literal string: "undefined". if (obj === undefined) { From 27cc30229d7d74e98d4919e97c9ea34fb8e34762 Mon Sep 17 00:00:00 2001 From: realdennis Date: Mon, 2 Sep 2019 12:16:14 +0800 Subject: [PATCH 2/7] docs. options.ignoreFunction --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c0edf01..3d6edd2 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,11 @@ serialize(obj, {isJSON: true}); This option is to signal `serialize()` that we want to do a straight conversion, without the XSS protection. This options needs to be explicitly set to `true`. HTML characters and JavaScript line terminators will not be escaped. You will have to roll your own. +#### `options.ignoreFunction` + +This option is to signal `serialize()` that we do not want serialize JavaScript function. +Just treat function like `JSON.stringify` do, but other features will work as expected. + ```js serialize(obj, {unsafe: true}); ``` From e6302f035804a36c272768918aff619e5a643f00 Mon Sep 17 00:00:00 2001 From: realdennis Date: Mon, 2 Sep 2019 12:29:33 +0800 Subject: [PATCH 3/7] Test. test case for the new option --- test/unit/serialize.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/unit/serialize.js b/test/unit/serialize.js index e66977c..a1175fa 100644 --- a/test/unit/serialize.js +++ b/test/unit/serialize.js @@ -424,6 +424,24 @@ describe('serialize( obj )', function () { expect(serialize(["<"], {space: 2})).to.equal('[\n "\\u003C"\n]'); expect(serialize(["<"], {unsafe: true, space: 2})).to.equal('[\n "<"\n]'); }); + + it("should accept a `ignoreFunction` option", function() { + function fn() { return true; } + const obj = { + fn, + fn_arrow: () => { + return true; + } + }; + const obj2 = { + num:123, + str:'str', + fn + } + expect(serialize(fn, { ignoreFunction: true })).to.equal(`undefined`); + expect(serialize(obj, { ignoreFunction: true })).to.equal("{}"); + expect(serialize(obj2,{ignoreFunction:true})).to.equal(`{"num":123,"str":"str"}`); + }); }); describe('backwards-compatability', function () { From b8be3e5a4a140b1c45995c7e4765278fac274276 Mon Sep 17 00:00:00 2001 From: realdennis Date: Mon, 2 Sep 2019 12:34:28 +0800 Subject: [PATCH 4/7] Modify the comment --- index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index e0bf6db..32b3aca 100644 --- a/index.js +++ b/index.js @@ -41,12 +41,8 @@ function deleteFunctions(obj){ for(var i=0; i typeof obj[key] === "function") - // .forEach(functionKey => { - // delete obj[functionKey]; - // }); } + module.exports = function serialize(obj, options) { options || (options = {}); @@ -65,9 +61,12 @@ module.exports = function serialize(obj, options) { // Returns placeholders for functions and regexps (identified by index) // which are later replaced by their string representation. function replacer(key, value) { + + // For nested function if(options.ignoreFunction){ deleteFunctions(value); } + if (!value && value !== undefined) { return value; } @@ -143,6 +142,7 @@ module.exports = function serialize(obj, options) { return serializedFn; } + // Check if the parameter is function if( options.ignoreFunction && typeof obj==='function'){ obj = undefined; } From ca4979ea2eebd21dc4081518e60f9c0d2f776939 Mon Sep 17 00:00:00 2001 From: realdennis Date: Mon, 2 Sep 2019 12:36:16 +0800 Subject: [PATCH 5/7] Add some comment for test case --- test/unit/serialize.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/unit/serialize.js b/test/unit/serialize.js index a1175fa..43bd116 100644 --- a/test/unit/serialize.js +++ b/test/unit/serialize.js @@ -438,9 +438,14 @@ describe('serialize( obj )', function () { str:'str', fn } + // case 1. Pass function to serialize expect(serialize(fn, { ignoreFunction: true })).to.equal(`undefined`); + // case 2. Pass function(arrow) in object to serialze expect(serialize(obj, { ignoreFunction: true })).to.equal("{}"); - expect(serialize(obj2,{ignoreFunction:true})).to.equal(`{"num":123,"str":"str"}`); + // case 3. Other features should work + expect(serialize(obj2, { ignoreFunction: true })).to.equal( + `{"num":123,"str":"str"}` + ); }); }); From 55df724bc5442a1cc439d1214a53fc03b762ab66 Mon Sep 17 00:00:00 2001 From: realdennis Date: Mon, 2 Sep 2019 17:56:10 +0800 Subject: [PATCH 6/7] Format the code --- index.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 32b3aca..cb4d771 100644 --- a/index.js +++ b/index.js @@ -32,14 +32,14 @@ function escapeUnsafeChars(unsafeChar) { } function deleteFunctions(obj){ - var functionKeys = [] - for(var key in obj){ - if(typeof obj[key] === 'function'){ - functionKeys.push(key); - } + var functionKeys = []; + for (var key in obj) { + if (typeof obj[key] === "function") { + functionKeys.push(key); + } } - for(var i=0; i Date: Mon, 2 Sep 2019 22:29:33 +0800 Subject: [PATCH 7/7] Code formatted & Docs update --- README.md | 6 +++++- index.js | 10 +++++----- test/unit/serialize.js | 24 ++++++++++++------------ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 3d6edd2..810fb57 100644 --- a/README.md +++ b/README.md @@ -101,13 +101,17 @@ serialize(obj, {isJSON: true}); This option is to signal `serialize()` that we want to do a straight conversion, without the XSS protection. This options needs to be explicitly set to `true`. HTML characters and JavaScript line terminators will not be escaped. You will have to roll your own. +```js +serialize(obj, {unsafe: true}); +``` + #### `options.ignoreFunction` This option is to signal `serialize()` that we do not want serialize JavaScript function. Just treat function like `JSON.stringify` do, but other features will work as expected. ```js -serialize(obj, {unsafe: true}); +serialize(obj, {ignoreFunction: true}); ``` ## Deserializing diff --git a/index.js b/index.js index cb4d771..67cd2d2 100644 --- a/index.js +++ b/index.js @@ -34,12 +34,12 @@ function escapeUnsafeChars(unsafeChar) { function deleteFunctions(obj){ var functionKeys = []; for (var key in obj) { - if (typeof obj[key] === "function") { - functionKeys.push(key); - } + if (typeof obj[key] === "function") { + functionKeys.push(key); + } } for (var i = 0; i < functionKeys.length; i++) { - delete obj[functionKeys[i]]; + delete obj[functionKeys[i]]; } } @@ -144,7 +144,7 @@ module.exports = function serialize(obj, options) { // Check if the parameter is function if (options.ignoreFunction && typeof obj === "function") { - obj = undefined; + obj = undefined; } // Protects against `JSON.stringify()` returning `undefined`, by serializing // to the literal string: "undefined". diff --git a/test/unit/serialize.js b/test/unit/serialize.js index 43bd116..6b8c19c 100644 --- a/test/unit/serialize.js +++ b/test/unit/serialize.js @@ -427,24 +427,24 @@ describe('serialize( obj )', function () { it("should accept a `ignoreFunction` option", function() { function fn() { return true; } - const obj = { - fn, - fn_arrow: () => { - return true; - } + var obj = { + fn: fn, + fn_arrow: () => { + return true; + } }; - const obj2 = { - num:123, - str:'str', - fn + var obj2 = { + num: 123, + str: 'str', + fn: fn } // case 1. Pass function to serialize - expect(serialize(fn, { ignoreFunction: true })).to.equal(`undefined`); + expect(serialize(fn, { ignoreFunction: true })).to.equal('undefined'); // case 2. Pass function(arrow) in object to serialze - expect(serialize(obj, { ignoreFunction: true })).to.equal("{}"); + expect(serialize(obj, { ignoreFunction: true })).to.equal('{}'); // case 3. Other features should work expect(serialize(obj2, { ignoreFunction: true })).to.equal( - `{"num":123,"str":"str"}` + '{"num":123,"str":"str"}' ); }); });