From 380157040afdb8d9260438d59c73a48e273303ca Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Thu, 20 Jul 2017 18:26:35 -0700 Subject: [PATCH] Fixed: prevent codegen'ing a function with an invalid name. This can happen when, for example, an RPC method name is the uppercase of a keyword like "Delete". --- lib/codegen/index.js | 24 ++++++++++++++++++++++++ lib/codegen/tests/index.js | 20 +++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/codegen/index.js b/lib/codegen/index.js index af005cb0f..8dcda99dc 100644 --- a/lib/codegen/index.js +++ b/lib/codegen/index.js @@ -1,6 +1,28 @@ "use strict"; module.exports = codegen; +var makeValidFunctionName = function() { + var memoized = {}; + + return function makeValidFunctionName(name) { + if ((name in memoized) && memoized[name]) { + return memoized[name]; + } + + try { + Function("return function " + name + "(){};"); + memoized[name] = name; + } catch (err) { + if (/^[a-z]+$/i.test(name)) { + memoized[name] = makeValidFunctionName(name + "_"); + } else { + memoized[name] = makeValidFunctionName(name.replace(/[^a-z]+/ig, '_')); + } + } + return memoized[name]; + }; +}(); + /** * Begins generating a function. * @memberof util @@ -16,6 +38,8 @@ function codegen(functionParams, functionName) { functionParams = undefined; } + functionName = makeValidFunctionName(functionName); + var body = []; /** diff --git a/lib/codegen/tests/index.js b/lib/codegen/tests/index.js index b189117d1..d4b0b4513 100644 --- a/lib/codegen/tests/index.js +++ b/lib/codegen/tests/index.js @@ -1,6 +1,6 @@ var codegen = require(".."); -// new require("benchmark").Suite().add("add", function() { +// new require("benchmark").Suite().add("add + delete", function() { var add = codegen(["a", "b"], "add") ("// awesome comment") @@ -10,4 +10,22 @@ var add = codegen(["a", "b"], "add") if (add(1, 2) !== 3) throw Error("failed"); +var object = { a: 1, b: 2 }; +var delete_ = codegen(["object", "property"], "delete3") + ("delete object[property];") + (); + +delete_(object, 'a'); + +if ("a" in object) + throw Error("expected 'a' property to be deleted but was not"); + +if (!delete_.name.includes('delete')) + throw Error("expected function name to contain 'delete': " + delete_.name); + +delete_(object, 'b'); + +if (JSON.stringify(object) !== '{}') + throw Error("unexpected JSON: " + JSON.stringify(object)); + // }).on("cycle", function(event) { process.stdout.write(String(event.target) + "\n"); }).run();