b02460fa63
Since commit c570011
dropped the `with` statement, this bit of
the test has only checked for writes to a specific variable
in the file.
There is no direct replacement for `with` here, the best we can
do (I think) is comparing property names on the global objects
before and after the `eval()` call.
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3132>
240 lines
5.7 KiB
JavaScript
240 lines
5.7 KiB
JavaScript
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
|
|
// Test cases for MessageTray URLification
|
|
|
|
const JsUnit = imports.jsUnit;
|
|
|
|
import 'resource:///org/gnome/shell/ui/environment.js';
|
|
|
|
import * as Assertions from '../common/assertions.js';
|
|
|
|
import * as JsParse from 'resource:///org/gnome/shell/misc/jsParse.js';
|
|
|
|
const HARNESS_COMMAND_HEADER = 'let imports = obj;' +
|
|
'let global = obj;' +
|
|
'let Main = obj;' +
|
|
'let foo = obj;' +
|
|
'let r = obj;';
|
|
|
|
const testsFindMatchingQuote = [
|
|
{
|
|
input: '"double quotes"',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '\'single quotes\'',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: 'some unquoted "some quoted"',
|
|
output: 14,
|
|
},
|
|
{
|
|
input: '"mixed \' quotes\'"',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '"escaped \\" quote"',
|
|
output: 0,
|
|
},
|
|
];
|
|
const testsFindMatchingSlash = [
|
|
{
|
|
input: '/slash/',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '/slash " with $ funny ^\' stuff/',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: 'some unslashed /some slashed/',
|
|
output: 15,
|
|
},
|
|
{
|
|
input: '/escaped \\/ slash/',
|
|
output: 0,
|
|
},
|
|
];
|
|
const testsFindMatchingBrace = [
|
|
{
|
|
input: '[square brace]',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '(round brace)',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '([()][nesting!])',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '[we have "quoted [" braces]',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '[we have /regex [/ braces]',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: '([[])[] mismatched braces ]',
|
|
output: 1,
|
|
},
|
|
];
|
|
const testsGetExpressionOffset = [
|
|
{
|
|
input: 'abc.123',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: 'foo().bar',
|
|
output: 0,
|
|
},
|
|
{
|
|
input: 'foo(bar',
|
|
output: 4,
|
|
},
|
|
{
|
|
input: 'foo[abc.match(/"/)]',
|
|
output: 0,
|
|
},
|
|
];
|
|
const testsGetDeclaredConstants = [
|
|
{
|
|
input: 'const foo = X; const bar = Y;',
|
|
output: ['foo', 'bar'],
|
|
},
|
|
{
|
|
input: 'const foo=X; const bar=Y',
|
|
output: ['foo', 'bar'],
|
|
},
|
|
];
|
|
const testsIsUnsafeExpression = [
|
|
{
|
|
input: 'foo.bar',
|
|
output: false,
|
|
},
|
|
{
|
|
input: 'foo[\'bar\']',
|
|
output: false,
|
|
},
|
|
{
|
|
input: 'foo["a=b=c".match(/=/)',
|
|
output: false,
|
|
},
|
|
{
|
|
input: 'foo[1==2]',
|
|
output: false,
|
|
},
|
|
{
|
|
input: '(x=4)',
|
|
output: true,
|
|
},
|
|
{
|
|
input: '(x = 4)',
|
|
output: true,
|
|
},
|
|
{
|
|
input: '(x;y)',
|
|
output: true,
|
|
},
|
|
];
|
|
const testsModifyScope = [
|
|
"foo['a",
|
|
"foo()['b'",
|
|
"obj.foo()('a', 1, 2, 'b')().",
|
|
'foo.[.',
|
|
'foo]]]()))].',
|
|
"123'ab\"",
|
|
'Main.foo.bar = 3; bar.',
|
|
'(Main.foo = 3).',
|
|
'Main[Main.foo+=-1].',
|
|
];
|
|
|
|
//
|
|
// Test javascript parsing
|
|
//
|
|
|
|
for (let i = 0; i < testsFindMatchingQuote.length; i++) {
|
|
let text = testsFindMatchingQuote[i].input;
|
|
let match = JsParse.findMatchingQuote(text, text.length - 1);
|
|
|
|
JsUnit.assertEquals(`Test testsFindMatchingQuote ${i}`,
|
|
match, testsFindMatchingQuote[i].output);
|
|
}
|
|
|
|
for (let i = 0; i < testsFindMatchingSlash.length; i++) {
|
|
let text = testsFindMatchingSlash[i].input;
|
|
let match = JsParse.findMatchingSlash(text, text.length - 1);
|
|
|
|
JsUnit.assertEquals(`Test testsFindMatchingSlash ${i}`,
|
|
match, testsFindMatchingSlash[i].output);
|
|
}
|
|
|
|
for (let i = 0; i < testsFindMatchingBrace.length; i++) {
|
|
let text = testsFindMatchingBrace[i].input;
|
|
let match = JsParse.findMatchingBrace(text, text.length - 1);
|
|
|
|
JsUnit.assertEquals(`Test testsFindMatchingBrace ${i}`,
|
|
match, testsFindMatchingBrace[i].output);
|
|
}
|
|
|
|
for (let i = 0; i < testsGetExpressionOffset.length; i++) {
|
|
let text = testsGetExpressionOffset[i].input;
|
|
let match = JsParse.getExpressionOffset(text, text.length - 1);
|
|
|
|
JsUnit.assertEquals(`Test testsGetExpressionOffset ${i}`,
|
|
match, testsGetExpressionOffset[i].output);
|
|
}
|
|
|
|
for (let i = 0; i < testsGetDeclaredConstants.length; i++) {
|
|
let text = testsGetDeclaredConstants[i].input;
|
|
let match = JsParse.getDeclaredConstants(text);
|
|
|
|
Assertions.assertArrayEquals(`Test testsGetDeclaredConstants ${i}`,
|
|
match, testsGetDeclaredConstants[i].output);
|
|
}
|
|
|
|
for (let i = 0; i < testsIsUnsafeExpression.length; i++) {
|
|
let text = testsIsUnsafeExpression[i].input;
|
|
let unsafe = JsParse.isUnsafeExpression(text);
|
|
|
|
JsUnit.assertEquals(`Test testsIsUnsafeExpression ${i}`,
|
|
unsafe, testsIsUnsafeExpression[i].output);
|
|
}
|
|
|
|
//
|
|
// Test safety of eval to get completions
|
|
//
|
|
|
|
for (let i = 0; i < testsModifyScope.length; i++) {
|
|
let text = testsModifyScope[i];
|
|
|
|
const globalPropsPre = Object.getOwnPropertyNames(globalThis).sort();
|
|
|
|
// Just as in JsParse.getCompletions, we will find the offset
|
|
// of the expression, test whether it is unsafe, and then eval it.
|
|
let offset = JsParse.getExpressionOffset(text, text.length - 1);
|
|
if (offset >= 0) {
|
|
text = text.slice(offset);
|
|
|
|
let matches = text.match(/(.*)\.(.*)/);
|
|
if (matches) {
|
|
let [, base] = matches;
|
|
|
|
if (!JsParse.isUnsafeExpression(base)) {
|
|
try {
|
|
eval(HARNESS_COMMAND_HEADER + base);
|
|
} catch (e) {
|
|
JsUnit.assertNotEquals(`Code '${base}' is valid code`, e.constructor, SyntaxError);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const globalPropsPost = Object.getOwnPropertyNames(globalThis).sort();
|
|
Assertions.assertArrayEquals('The global object was not modified',
|
|
globalPropsPre, globalPropsPost);
|
|
}
|