403Webshell
Server IP : 185.208.173.17  /  Your IP : 87.236.161.98
Web Server : Microsoft-IIS/10.0
System : Windows NT SRV8576125506 10.0 build 26100 (Windows Server 2016) AMD64
User : IUSR ( 0)
PHP Version : 7.4.13
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/inetpub/wwwroot/parsmega.nuxt/node_modules/eslint-template-visitor/lib/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : C:/inetpub/wwwroot/parsmega.nuxt/node_modules/eslint-template-visitor/lib/index.test.js
const test = require('ava');
const sinon = require('sinon');

const { omit, times } = require('ramda');

const { default: fuzzProgram, FuzzerState } = require('shift-fuzzer');
const { default: shiftCodegen, FormattedCodeGen } = require('shift-codegen');

const { parse: babelEslintParse } = require('@babel/eslint-parser');

const seedrandom = require('seedrandom');

const shiftToEspreeSafe = require('../test/_shift-to-espree-safe');
const dropExtraTopLevelNodes = require('../test/_drop-extra-top-level-nodes');
const babelEslintWorkarounds = require('../test/_babel-eslint-parser-workarounds');
const { parse, PARSER } = require('../test/_parser');

const recurse = require('./recurse');

const eslintTemplateVisitor = require('.');

const SEED = process.env.SEED || Math.random().toString(16).slice(2);

console.log(`
Reproduce the randomized fuzzing test by running:
\`\`\`bash
SEED=${JSON.stringify(SEED)} npm test
\`\`\`
`);

const parserOptions = {
	sourceType: 'module',
	ecmaVersion: 2018,
	requireConfigFile: false,
};

test.beforeEach(t => {
	t.context.rng = seedrandom(SEED);
});

test('mixing templates into a visitor', t => {
	const templates = eslintTemplateVisitor();

	const a = templates.variable();
	const template = templates.template`${a}.parentNode.removeChild(${a})`;

	const ast = parse(`
		foo.parentNode.removeChild(foo);
		foo.parentNode.removeChild(bar);
	`, parserOptions);

	const visitorA = {
		[template]: sinon.spy(),
		CallExpression: sinon.spy(),
		MemberExpression: sinon.spy(),
	};

	const visitorB = {
		[template]: sinon.spy(),
		MemberExpression: sinon.spy(),
	};

	recurse.visit(ast, visitorA);
	recurse.visit(ast, templates.visitor(visitorB));

	t.false(visitorA[template].called);
	t.true(visitorA.CallExpression.called);
	t.true(visitorA.MemberExpression.called);

	t.true(visitorB[template].called);
	t.true(visitorB.MemberExpression.called);

	t.deepEqual(
		visitorA.MemberExpression.getCalls().map(call => call.args),
		visitorB.MemberExpression.getCalls().map(call => call.args),
	);

	t.deepEqual(
		visitorA.CallExpression.getCalls().map(call => call.args).slice(0, 1),
		visitorB[template].getCalls().map(call => call.args),
	);
});

test('variable matching', t => {
	const templates = eslintTemplateVisitor();

	const a = templates.variable();
	const template = templates.template`${a}.foo()`;

	const visitor = {
		[template]: sinon.spy(),
	};

	recurse.visit(parse('foo.bar()', parserOptions), templates.visitor(visitor));
	t.false(visitor[template].called);

	recurse.visit(parse('bar.foo()', parserOptions), templates.visitor(visitor));
	t.true(visitor[template].called);
});

const templateFoundInMacro = (t, templateSource, source, expectedToMatch = true) => {
	const templates = eslintTemplateVisitor({ parserOptions });
	const template = templates.template(templateSource);

	const visitor = {
		[template]: sinon.spy(),
	};

	recurse.visit(parse(source, parserOptions), templates.visitor(visitor));
	t.is(visitor[template].called, expectedToMatch);
};

templateFoundInMacro.title = (_, templateSource, source, expectedToMatch = true) => {
	return `\`${templateSource}\` ${expectedToMatch ? 'should be found in' : 'should not be found in'} \`${source}\``;
};

const templateMatchesMacro = (t, templateSource, source, expectedToMatch = true) => {
	const wrap = s => `uniqueEnoughIdentifier((${s}))`;
	templateFoundInMacro(t, wrap(templateSource), wrap(source), expectedToMatch);
};

templateMatchesMacro.title = (_, templateSource, source, expectedToMatch = true) => {
	return `\`${templateSource}\` ${expectedToMatch ? 'should match' : 'should not match'} \`${source}\``;
};

test(templateMatchesMacro, 'foo', 'bar', false);
test(templateMatchesMacro, 'foo', 'foo');

test(templateMatchesMacro, 'foo.bar', 'foo.bar');
test(templateMatchesMacro, 'foo.bar', 'foo["bar"]', false);
test(templateMatchesMacro, 'foo.bar', 'foo.quz', false);
test(templateMatchesMacro, 'foo.bar', 'quz.bar', false);

test(templateMatchesMacro, 'foo.bar()', 'foo.bar()');
test(templateMatchesMacro, 'foo.bar()', 'foo["bar"]()', false);
test(templateMatchesMacro, 'foo.bar()', 'foo.quz()', false);
test(templateMatchesMacro, 'foo.bar()', 'quz.bar()', false);

test(templateFoundInMacro, 'x', '[a, b, c]', false);
test(templateFoundInMacro, 'b', '[a, b, c]');

test(templateMatchesMacro, '1', '2', false);
test(templateMatchesMacro, '1', '1');

test(templateFoundInMacro, '9', '[1, 2, 3]', false);
test(templateFoundInMacro, '2', '[1, 2, 3]');

test(templateFoundInMacro, '({})', '({a:[]})', false);
test(templateFoundInMacro, '({})', '[{}]');

test(templateMatchesMacro, '(() => {})', '(function() {})', false);
test(templateMatchesMacro, '(( ) => { })', '(()=>{})');

test(templateMatchesMacro, 'NaN', '-NaN', false);
test(templateMatchesMacro, 'NaN', 'NaN');

test(templateFoundInMacro, 'NaN', 'NaN');
test(templateFoundInMacro, 'NaN', '-NaN');
test(templateFoundInMacro, '-NaN', '+NaN', false);
test(templateFoundInMacro, '+NaN', '-NaN', false);

test(templateMatchesMacro, '/a/', '/a/g', false);
test(templateMatchesMacro, '/a/', '/a/');

test(templateFoundInMacro, '/x/', 'foo(/x/)');
test(templateFoundInMacro, '/x/', 'foo(/x/y)', false);

test(templateMatchesMacro, '0', '+0', false);
test(templateMatchesMacro, '0', '-0', false);
test(templateMatchesMacro, '0', '0');

test(templateFoundInMacro, '0', '+0');
test(templateFoundInMacro, '0', '-0');
test(templateFoundInMacro, '0', '0');
test(templateFoundInMacro, '-0', '0', false);
test(templateFoundInMacro, '+0', '0', false);

test('variable values', t => {
	t.plan(6);

	const templates = eslintTemplateVisitor();

	const receiver = templates.variable();
	const method = templates.variable();
	const template = templates.template`${receiver}.${method}()`;

	const visitor = {
		[template](node) {
			const receiverNode = template.context.getMatch(receiver);
			const methodNode = template.context.getMatch(method);

			t.is(node.type, 'CallExpression');
			t.is(node.arguments.length, 0);

			t.is(receiverNode.type, 'Identifier');
			t.is(receiverNode.name, 'bar');

			t.is(methodNode.type, 'Identifier');
			t.is(methodNode.name, 'foo');
		},
	};

	// Should match
	recurse.visit(parse('bar.foo()', parserOptions), templates.visitor(visitor));

	// Should not match
	recurse.visit(parse('bar.foo(argument)', parserOptions), templates.visitor(visitor));
	recurse.visit(parse('bar.foo(...arguments)', parserOptions), templates.visitor(visitor));
});

test('`spreadVariable` matching arguments', t => {
	const templates = eslintTemplateVisitor();

	const argumentsVariable = templates.spreadVariable();
	const template = templates.template`receiver.method(${argumentsVariable})`;

	const recordedArguments = [];

	const visitor = {
		[template](node) {
			const argumentNodes = template.context.getMatch(argumentsVariable);

			recordedArguments.push(argumentNodes);

			t.is(node.type, 'CallExpression');
			t.is(node.arguments, argumentNodes);
		},
	};

	recurse.visit(parse('receiver.method()', parserOptions), templates.visitor(visitor));

	t.is(recordedArguments.length, 1);
	t.deepEqual(recordedArguments[0], []);

	recurse.visit(parse('receiver.method(onlyArgument)', parserOptions), templates.visitor(visitor));

	t.is(recordedArguments.length, 2);
	t.is(recordedArguments[1].length, 1);

	recurse.visit(parse('receiver.method(argument1, argument2)', parserOptions), templates.visitor(visitor));

	t.is(recordedArguments.length, 3);
	t.is(recordedArguments[2].length, 2);

	recurse.visit(parse('receiver.method(...arguments)', parserOptions), templates.visitor(visitor));

	t.is(recordedArguments.length, 4);
	t.is(recordedArguments[3].length, 1);
	t.is(recordedArguments[3][0].type, 'SpreadElement');
});

test('`spreadVariable` matching statements', t => {
	const templates = eslintTemplateVisitor({ parserOptions });

	const statementsVariable = templates.spreadVariable();
	const template = templates.template`() => {${statementsVariable}}`;

	const recordedStatements = [];

	const visitor = {
		[template](node) {
			const statementNodes = template.context.getMatch(statementsVariable);

			recordedStatements.push(statementNodes);

			t.is(node.type, 'ArrowFunctionExpression');
			t.is(node.body.type, 'BlockStatement');
			t.is(node.body.body, statementNodes);
		},
	};

	recurse.visit(parse('() => {}', parserOptions), templates.visitor(visitor));

	t.is(recordedStatements.length, 1);
	t.deepEqual(recordedStatements[0], []);

	recurse.visit(parse('() => { onlyStatement; }', parserOptions), templates.visitor(visitor));

	t.is(recordedStatements.length, 2);
	t.is(recordedStatements[1].length, 1);

	recurse.visit(parse('() => { statement1; statement2 }', parserOptions), templates.visitor(visitor));

	t.is(recordedStatements.length, 3);
	t.is(recordedStatements[2].length, 2);
});

test('`variableDeclarationVariable` matching variable declarations', t => {
	const templates = eslintTemplateVisitor({ parserOptions });

	const variableDeclarationVariable = templates.variableDeclarationVariable();
	const template = templates.template`() => {
		${variableDeclarationVariable} x = y;
	}`;

	const recordedVariableDeclarations = [];

	const visitor = {
		[template](node) {
			const variableDeclarationNode = template.context.getMatch(variableDeclarationVariable);

			recordedVariableDeclarations.push(variableDeclarationNode);

			t.is(node.type, 'ArrowFunctionExpression');
			t.is(node.body.type, 'BlockStatement');
			t.deepEqual(node.body.body[0], variableDeclarationNode);
		},
	};

	recurse.visit(parse('() => {}', parserOptions), templates.visitor(visitor));

	t.deepEqual(recordedVariableDeclarations, []);

	recurse.visit(parse('() => { x = y; }', parserOptions), templates.visitor(visitor));

	t.deepEqual(recordedVariableDeclarations, []);

	recurse.visit(parse('() => { const x = y; }', parserOptions), templates.visitor(visitor));

	t.is(recordedVariableDeclarations.length, 1);
	t.is(recordedVariableDeclarations[0].kind, 'const');

	recurse.visit(parse('() => { let x = y; }', parserOptions), templates.visitor(visitor));

	t.is(recordedVariableDeclarations.length, 2);
	t.is(recordedVariableDeclarations[1].kind, 'let');

	recurse.visit(parse('() => { var x = y; }', parserOptions), templates.visitor(visitor));

	t.is(recordedVariableDeclarations.length, 3);
	t.is(recordedVariableDeclarations[2].kind, 'var');
});

test('`variableDeclarationVariable` unification', t => {
	const templates = eslintTemplateVisitor({ parserOptions });

	const variableDeclarationVariable = templates.variableDeclarationVariable();
	const variableVariable = templates.variable();
	const template = templates.template`{
		${variableDeclarationVariable} ${variableVariable};
		${variableDeclarationVariable} ${variableVariable};
	}`;

	const recordedVariableDeclarations = [];
	const recordedVariables = [];

	const visitor = {
		[template](node) {
			const variableDeclarationNode = template.context.getMatch(variableDeclarationVariable);
			const variableNode = template.context.getMatch(variableVariable);

			recordedVariableDeclarations.push(variableDeclarationNode);
			recordedVariables.push(variableNode);

			t.is(node.type, 'BlockStatement');
		},
	};

	recurse.visit(parse('() => { var x; var x; }', parserOptions), templates.visitor(visitor));

	t.is(recordedVariableDeclarations.length, 1);
	t.is(recordedVariableDeclarations[0].kind, 'var');

	t.is(recordedVariables.length, 1);
	t.is(recordedVariables[0].type, 'Identifier');
	t.is(recordedVariables[0].name, 'x');
});

const omitLocation = omit([
	'start',
	'end',
	'loc',
	'range',
]);

test('variable unification', t => {
	t.plan(6);

	const templates = eslintTemplateVisitor();

	const x = templates.variable();
	const template = templates.template`${x} + ${x}`;

	const visitor = {
		[template](node) {
			t.is(node.type, 'BinaryExpression');

			const xNodes = template.context.getMatches(x);

			t.is(xNodes.length, 2);

			const [ x1, x2 ] = xNodes;

			t.is(x1.type, 'Identifier');
			t.is(x1.name, 'foo');

			t.not(x1, x2);
			t.deepEqual(omitLocation(x1), omitLocation(x2));
		},
	};

	// Should match
	recurse.visit(parse('foo + foo', parserOptions), templates.visitor(visitor));

	// Should not match
	recurse.visit(parse('foo + bar', parserOptions), templates.visitor(visitor));
	recurse.visit(parse('bar + foo', parserOptions), templates.visitor(visitor));
});

test('throws on multiple top-level nodes in a template', t => {
	const templates = eslintTemplateVisitor({ parserOptions });

	t.throws(() => {
		return templates.template`a; b;`;
	});
});

test('narrow to a statement with await', t => {
	const templates = eslintTemplateVisitor({ parserOptions });

	const template = templates.template`
		async () => { await 1; }
	`.narrow('BlockStatement > :has(AwaitExpression)');

	const source = 'async () => { await 0; await 1; await 2; }';

	const visitor = {
		[template]: sinon.spy(),
	};

	recurse.visit(parse(source, parserOptions), templates.visitor(visitor));
	t.true(visitor[template].called);
	t.is(visitor[template].callCount, 1);
});

if (PARSER === '@babel/eslint-parser') {
	test('dynamic import', t => {
		const templates = eslintTemplateVisitor({ parserOptions });

		const template = templates.template`import('foo')`;

		const source = 'async () => { await import(\'bar\'); await import(\'foo\'); await import(\'qux\'); }';

		const visitor = {
			[template]: sinon.spy(),
		};

		recurse.visit(parse(source, parserOptions), templates.visitor(visitor));
		t.true(visitor[template].called);
		t.is(visitor[template].callCount, 1);
	});
}

test('fuzzing', t => {
	const { rng } = t.context;

	const templates = eslintTemplateVisitor({ parserOptions });

	const totalTests = 2 ** 13;
	let skippedTests = 0;

	times(() => {
		const randomShiftAST = fuzzProgram(new FuzzerState({ rng, maxDepth: 3 }));
		const randomEspreeSafeShiftAST = shiftToEspreeSafe(dropExtraTopLevelNodes(randomShiftAST));
		const randomJS = shiftCodegen(randomEspreeSafeShiftAST, new FormattedCodeGen()) || '"empty program";';

		try {
			const { shouldSkip } = babelEslintWorkarounds(babelEslintParse(randomJS, parserOptions));

			if (shouldSkip) {
				console.warn('Ignored a random script due to a `@babel/eslint-parser` bug (this is fine):', randomJS);
				skippedTests += 1;
				return;
			}
		} catch (error) {
			if (error.name === 'SyntaxError') {
				// TODO: `shiftToEspreeSafe` or `fuzzProgram` should do a better job ensuring program is valid
				console.warn('Ignored error (this is fine):', error.name + ':', error.message);
				skippedTests += 1;
				return;
			}

			throw error;
		}

		const randomTemplate = templates.template(randomJS);
		const randomAST = parse(randomJS, parserOptions);

		const visitor = {
			[randomTemplate]: sinon.spy(),
		};

		recurse.visit(randomAST, templates.visitor(visitor));

		const { called } = visitor[randomTemplate];

		t.true(called);

		if (!called) {
			console.dir({
				randomJS,
				randomEspreeSafeShiftAST,
				randomAST,
			}, { depth: null });

			throw new Error('Fuzzing test failed. This error is thrown just to stop this long test early.');
		}
	}, totalTests);

	console.log({
		skippedTests,
		totalTests,
	});
});

Youez - 2016 - github.com/yon3zu
LinuXploit