Skip to content

Commit

Permalink
BugFix3290:Should the Parser.set function validate variable names
Browse files Browse the repository at this point in the history
  • Loading branch information
nkumawat34 committed Nov 3, 2024
1 parent 982bbdc commit cbfdd51
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/expression/Parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { factory } from '../utils/factory.js'
import { createEmptyMap, toObject } from '../utils/map.js'

const name = 'Parser'
const dependencies = ['evaluate']
const dependencies = ['evaluate', 'parse']

export const createParserClass = /* #__PURE__ */ factory(name, dependencies, ({ evaluate }) => {
export const createParserClass = /* #__PURE__ */ factory(name, dependencies, ({ evaluate, parse }) => {
/**
* @constructor Parser
* Parser contains methods to evaluate or parse expressions, and has a number
Expand Down Expand Up @@ -112,12 +112,32 @@ export const createParserClass = /* #__PURE__ */ factory(name, dependencies, ({
return this.scope
}

function isValidVariableName (name) {
if (name.length === 0) { return false }

for (let i = 0; i < name.length; i++) {
const cPrev = name.charAt(i - 1)
const c = name.charAt(i)
const cNext = name.charAt(i + 1)
const valid = parse.isAlpha(c, cPrev, cNext) || (i > 0 && parse.isDigit(c))

if (!valid) {
return false
}
}

return true
}

/**
* Set a symbol (a function or variable) by name from the parsers scope.
* @param {string} name
* @param {* | undefined} value
*/
Parser.prototype.set = function (name, value) {
if (!isValidVariableName(name)) {
throw new Error(`Invalid variable name: '${name}'. Variable names must follow the specified rules.`)
}
this.scope.set(name, value)
return value
}
Expand Down
18 changes: 18 additions & 0 deletions test/unit-tests/expression/Parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,24 @@ describe('parser', function () {
assert.strictEqual(parser.evaluate('pi'), Math.PI)
})

it('should validate variable names', function () {
const parser = new Parser()

// Valid variable names
assert.strictEqual(parser.set('validVar', 42), 42)
assert.strictEqual(parser.evaluate('validVar'), 42)
assert.strictEqual(parser.set('_underscoreVar', 10), 10)
assert.strictEqual(parser.evaluate('_underscoreVar'), 10)
assert.strictEqual(parser.set('var123', 100), 100)
assert.strictEqual(parser.evaluate('var123'), 100)

// Invalid variable names
assert.throws(() => parser.set('123var', 5), /Invalid variable name/)
assert.throws(() => parser.set('var-with-hyphen', 5), /Invalid variable name/)
assert.throws(() => parser.set('var with space', 5), /Invalid variable name/)
assert.throws(() => parser.set('@specialChar', 5), /Invalid variable name/)
})

describe('security', function () {
it('should return undefined when accessing what appears to be inherited properties', function () {
try {
Expand Down

0 comments on commit cbfdd51

Please sign in to comment.