Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Socket Community Patch: https://socket.dev
// Date: Mon, 22 Jun 2026 23:36:07 GMT
// For more information see https://socket.dev/patch/741aacbe-4f2d-44ce-bb6c-080c68ca0719
// This file includes modifications made by Socket, Inc. on Mon, 22 Jun 2026; these modifications are called the "Patch". In some cases, Socket may be required to make the Patch available to you under specific terms, or may be prohibited from restricting certain rights you may have. For example, the terms of another applicable license may require Socket to make the Patch available under specific terms. In those cases, the Patch is made available to you under the required terms, and Socket does not seek to restrict your rights relative to the Patch where prohibited. In all other cases, the Patch is available to you exclusively under the PolyForm Shield License 1.0.0 (https://polyformproject.org/licenses/shield/1.0.0/). The Patch was distributed by Socket with additional information concerning licensing, attribution, and limitation of liability which may be relevant to you and your use of the Patch. As far as the law allows, the Patch and the software including the patch come as is, without any warranty or condition, and Socket will not be liable to you for any damages arising out of the applicable license terms or the use or nature of the Patch or the software including the patch, under any kind of legal claim.
// Original License: MIT

import parser from './parser';
import WhitespaceControl from './whitespace-control';
import * as Helpers from './helpers';
import Exception from '../exception';
import { extend } from '../utils';

export { parser };

let yy = {};
extend(yy, Helpers);

export function parseWithoutProcessing(input, options) {
// Just return if an already-compiled AST was passed in.
if (input.type === 'Program') {
// When a pre-parsed AST is passed in, validate all node values to prevent
// code injection via type-confused literals.
validateInputAst(input);
return input;
}

parser.yy = yy;

// Altering the shared object here, but this is ok as parser is a sync operation
yy.locInfo = function(locInfo) {
return new yy.SourceLocation(options && options.srcName, locInfo);
};

let ast = parser.parse(input);

return ast;
}

export function parse(input, options) {
let ast = parseWithoutProcessing(input, options);
let strip = new WhitespaceControl(options);

return strip.accept(ast);
}

function validateInputAst(ast) {
validateAstNode(ast);
}

function validateAstNode(node) {
if (node == null) {
return;
}

if (Array.isArray(node)) {
node.forEach(validateAstNode);
return;
}

if (typeof node !== 'object') {
return;
}

if (node.type === 'PathExpression') {
if (!isValidDepth(node.depth)) {
throw new Exception(
'Invalid AST: PathExpression.depth must be an integer'
);
}
if (!Array.isArray(node.parts)) {
throw new Exception('Invalid AST: PathExpression.parts must be an array');
}
for (let i = 0; i < node.parts.length; i++) {
if (typeof node.parts[i] !== 'string') {
throw new Exception(
'Invalid AST: PathExpression.parts must only contain strings'
);
}
}
} else if (node.type === 'NumberLiteral') {
if (typeof node.value !== 'number' || !isFinite(node.value)) {
throw new Exception('Invalid AST: NumberLiteral.value must be a number');
}
} else if (node.type === 'BooleanLiteral') {
if (typeof node.value !== 'boolean') {
throw new Exception(
'Invalid AST: BooleanLiteral.value must be a boolean'
);
}
}

Object.keys(node).forEach(propertyName => {
if (propertyName === 'loc') {
return;
}
validateAstNode(node[propertyName]);
});
}

function isValidDepth(depth) {
return (
typeof depth === 'number' &&
isFinite(depth) &&
Math.floor(depth) === depth &&
depth >= 0
);
}
Loading
Loading