Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
GarboMuffin committed Aug 22, 2023
1 parent 55cda82 commit 6836209
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 117 deletions.
20 changes: 5 additions & 15 deletions test/integration/tw_privacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,23 +94,13 @@ test('custom extensions', async t => {
vm.attachRenderer(mockRenderer());

vm.extensionManager.securityManager.getSandboxMode = () => 'unsandboxed';
global.document = {
createElement: () => {
const element = {};
setTimeout(() => {
global.Scratch.extensions.register({
getInfo: () => ({})
});
});
return element;
},
body: {
appendChild: () => {}
}
};
global.fetch = () => Promise.resolve({
ok: true,
text: () => Promise.resolve('Scratch.extensions.register({getInfo: () => ({id: "test", blocks: []})})')
});

t.equal(vm.renderer.privateSkinAccess, true);
await vm.extensionManager.loadExtensionURL('data:application/javascript;,');
await vm.extensionManager.loadExtensionURL('data:application/javascript;,fake URL see fetch() mock');
t.equal(vm.renderer.privateSkinAccess, false);
t.end();
});
156 changes: 78 additions & 78 deletions test/integration/tw_security_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const {test} = require('tap');
const fs = require('fs');
const path = require('path');
const VirtualMachine = require('../../src/virtual-machine');
const {setupUnsandboxedExtensionAPI} = require('../../src/extension-support/tw-unsandboxed-extension-runner');
const {createAPI} = require('../../src/extension-support/tw-unsandboxed-extension-runner');

const testProject = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'tw-project-with-extensions.sb3'));

Expand Down Expand Up @@ -67,49 +67,49 @@ test('Allow both extensions', async t => {

test('canFetch', async t => {
const vm = new VirtualMachine();
setupUnsandboxedExtensionAPI(vm);
const api = createAPI(vm);
global.location = {
href: 'https://example.com/'
};

// data: and blob: are always allowed, shouldn't call security manager
vm.securityManager.canFetch = () => t.fail('security manager should be ignored for these protocols');
t.equal(await global.Scratch.canFetch('data:text/html,test'), true);
t.equal(await global.Scratch.canFetch('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), true);
t.equal(await api.Scratch.canFetch('data:text/html,test'), true);
t.equal(await api.Scratch.canFetch('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), true);

vm.securityManager.canFetch = () => false;
t.equal(await global.Scratch.canFetch('file:///etc/hosts'), false);
t.equal(await global.Scratch.canFetch('http://example.com/'), false);
t.equal(await global.Scratch.canFetch('https://example.com/'), false);
t.equal(await global.Scratch.canFetch('null'), false);
t.equal(await global.Scratch.canFetch(null), false);
t.equal(await api.Scratch.canFetch('file:///etc/hosts'), false);
t.equal(await api.Scratch.canFetch('http://example.com/'), false);
t.equal(await api.Scratch.canFetch('https://example.com/'), false);
t.equal(await api.Scratch.canFetch('null'), false);
t.equal(await api.Scratch.canFetch(null), false);

vm.securityManager.canFetch = () => Promise.resolve(false);
t.equal(await global.Scratch.canFetch('file:///etc/hosts'), false);
t.equal(await global.Scratch.canFetch('http://example.com/'), false);
t.equal(await global.Scratch.canFetch('https://example.com/'), false);
t.equal(await global.Scratch.canFetch('boring.html'), false);
t.equal(await global.Scratch.canFetch('null'), false);
t.equal(await global.Scratch.canFetch(null), false);
t.equal(await api.Scratch.canFetch('file:///etc/hosts'), false);
t.equal(await api.Scratch.canFetch('http://example.com/'), false);
t.equal(await api.Scratch.canFetch('https://example.com/'), false);
t.equal(await api.Scratch.canFetch('boring.html'), false);
t.equal(await api.Scratch.canFetch('null'), false);
t.equal(await api.Scratch.canFetch(null), false);

vm.securityManager.canFetch = () => true;
t.equal(await global.Scratch.canFetch('file:///etc/hosts'), true);
t.equal(await global.Scratch.canFetch('http://example.com/'), true);
t.equal(await global.Scratch.canFetch('https://example.com/'), true);
t.equal(await global.Scratch.canFetch('boring.html'), true);
t.equal(await global.Scratch.canFetch('null'), true);
t.equal(await global.Scratch.canFetch(null), true);
t.equal(await api.Scratch.canFetch('file:///etc/hosts'), true);
t.equal(await api.Scratch.canFetch('http://example.com/'), true);
t.equal(await api.Scratch.canFetch('https://example.com/'), true);
t.equal(await api.Scratch.canFetch('boring.html'), true);
t.equal(await api.Scratch.canFetch('null'), true);
t.equal(await api.Scratch.canFetch(null), true);

const calledWithURLs = [];
vm.securityManager.canFetch = async url => {
calledWithURLs.push(url);
return url === 'https://example.com/null';
};
t.equal(await global.Scratch.canFetch('file:///etc/hosts'), false);
t.equal(await global.Scratch.canFetch('http://example.com/'), false);
t.equal(await global.Scratch.canFetch('https://example.com/null'), true);
t.equal(await global.Scratch.canFetch('null'), true);
t.equal(await global.Scratch.canFetch(null), true);
t.equal(await api.Scratch.canFetch('file:///etc/hosts'), false);
t.equal(await api.Scratch.canFetch('http://example.com/'), false);
t.equal(await api.Scratch.canFetch('https://example.com/null'), true);
t.equal(await api.Scratch.canFetch('null'), true);
t.equal(await api.Scratch.canFetch(null), true);
t.same(calledWithURLs, [
'file:///etc/hosts',
'http://example.com/',
Expand All @@ -123,50 +123,50 @@ test('canFetch', async t => {

test('canOpenWindow', async t => {
const vm = new VirtualMachine();
setupUnsandboxedExtensionAPI(vm);
const api = createAPI(vm);
global.location = {
href: 'https://example.com/'
};

// javascript: should never be allowed, shouldn't call security manager
vm.securityManager.canOpenWindow = () => t.fail('should not call security manager for javascript:');
t.equal(await global.Scratch.canOpenWindow('javascript:alert(1)'), false);
t.equal(await api.Scratch.canOpenWindow('javascript:alert(1)'), false);

vm.securityManager.canOpenWindow = () => false;
t.equal(await global.Scratch.canOpenWindow('data:text/html,test'), false);
t.equal(await global.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await global.Scratch.canOpenWindow('file:///etc/hosts'), false);
t.equal(await global.Scratch.canOpenWindow('https://example.com/'), false);
t.equal(await global.Scratch.canOpenWindow('index.html'), false);
t.equal(await global.Scratch.canOpenWindow(null), false);
t.equal(await api.Scratch.canOpenWindow('data:text/html,test'), false);
t.equal(await api.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await api.Scratch.canOpenWindow('file:///etc/hosts'), false);
t.equal(await api.Scratch.canOpenWindow('https://example.com/'), false);
t.equal(await api.Scratch.canOpenWindow('index.html'), false);
t.equal(await api.Scratch.canOpenWindow(null), false);

vm.securityManager.canOpenWindow = () => Promise.resolve(false);
t.equal(await global.Scratch.canOpenWindow('data:text/html,test'), false);
t.equal(await global.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await global.Scratch.canOpenWindow('file:///etc/hosts'), false);
t.equal(await global.Scratch.canOpenWindow('https://example.com/'), false);
t.equal(await global.Scratch.canOpenWindow('index.html'), false);
t.equal(await global.Scratch.canOpenWindow(null), false);
t.equal(await api.Scratch.canOpenWindow('data:text/html,test'), false);
t.equal(await api.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await api.Scratch.canOpenWindow('file:///etc/hosts'), false);
t.equal(await api.Scratch.canOpenWindow('https://example.com/'), false);
t.equal(await api.Scratch.canOpenWindow('index.html'), false);
t.equal(await api.Scratch.canOpenWindow(null), false);

vm.securityManager.canOpenWindow = () => true;
t.equal(await global.Scratch.canOpenWindow('data:text/html,test'), true);
t.equal(await global.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), true);
t.equal(await global.Scratch.canOpenWindow('file:///etc/hosts'), true);
t.equal(await global.Scratch.canOpenWindow('https://example.com/'), true);
t.equal(await global.Scratch.canOpenWindow('index.html'), true);
t.equal(await global.Scratch.canOpenWindow(null), true);
t.equal(await api.Scratch.canOpenWindow('data:text/html,test'), true);
t.equal(await api.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), true);
t.equal(await api.Scratch.canOpenWindow('file:///etc/hosts'), true);
t.equal(await api.Scratch.canOpenWindow('https://example.com/'), true);
t.equal(await api.Scratch.canOpenWindow('index.html'), true);
t.equal(await api.Scratch.canOpenWindow(null), true);

const calledWithURLs = [];
vm.securityManager.canOpenWindow = async url => {
calledWithURLs.push(url);
return url === 'file:///etc/hosts';
};
t.equal(await global.Scratch.canOpenWindow('data:text/html,test'), false);
t.equal(await global.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await global.Scratch.canOpenWindow('file:///etc/hosts'), true);
t.equal(await global.Scratch.canOpenWindow('https://example.com/'), false);
t.equal(await global.Scratch.canOpenWindow('index.html'), false);
t.equal(await global.Scratch.canOpenWindow(null), false);
t.equal(await api.Scratch.canOpenWindow('data:text/html,test'), false);
t.equal(await api.Scratch.canOpenWindow('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await api.Scratch.canOpenWindow('file:///etc/hosts'), true);
t.equal(await api.Scratch.canOpenWindow('https://example.com/'), false);
t.equal(await api.Scratch.canOpenWindow('index.html'), false);
t.equal(await api.Scratch.canOpenWindow(null), false);
t.same(calledWithURLs, [
'data:text/html,test',
'blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd',
Expand All @@ -181,50 +181,50 @@ test('canOpenWindow', async t => {

test('canRedirect', async t => {
const vm = new VirtualMachine();
setupUnsandboxedExtensionAPI(vm);
const api = createAPI(vm);
global.location = {
href: 'https://example.com/'
};

// javascript: should never be allowed, shouldn't call security manager
vm.securityManager.canRedirect = () => t.fail('should not call security manager for javascript:');
t.equal(await global.Scratch.canRedirect('javascript:alert(1)'), false);
t.equal(await api.Scratch.canRedirect('javascript:alert(1)'), false);

vm.securityManager.canRedirect = () => false;
t.equal(await global.Scratch.canRedirect('data:text/html,test'), false);
t.equal(await global.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await global.Scratch.canRedirect('file:///etc/hosts'), false);
t.equal(await global.Scratch.canRedirect('https://example.com/'), false);
t.equal(await global.Scratch.canRedirect('index.html'), false);
t.equal(await global.Scratch.canRedirect(null), false);
t.equal(await api.Scratch.canRedirect('data:text/html,test'), false);
t.equal(await api.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await api.Scratch.canRedirect('file:///etc/hosts'), false);
t.equal(await api.Scratch.canRedirect('https://example.com/'), false);
t.equal(await api.Scratch.canRedirect('index.html'), false);
t.equal(await api.Scratch.canRedirect(null), false);

vm.securityManager.canRedirect = () => Promise.resolve(false);
t.equal(await global.Scratch.canRedirect('data:text/html,test'), false);
t.equal(await global.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await global.Scratch.canRedirect('file:///etc/hosts'), false);
t.equal(await global.Scratch.canRedirect('https://example.com/'), false);
t.equal(await global.Scratch.canRedirect('index.html'), false);
t.equal(await global.Scratch.canRedirect(null), false);
t.equal(await api.Scratch.canRedirect('data:text/html,test'), false);
t.equal(await api.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await api.Scratch.canRedirect('file:///etc/hosts'), false);
t.equal(await api.Scratch.canRedirect('https://example.com/'), false);
t.equal(await api.Scratch.canRedirect('index.html'), false);
t.equal(await api.Scratch.canRedirect(null), false);

vm.securityManager.canRedirect = () => true;
t.equal(await global.Scratch.canRedirect('data:text/html,test'), true);
t.equal(await global.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), true);
t.equal(await global.Scratch.canRedirect('file:///etc/hosts'), true);
t.equal(await global.Scratch.canRedirect('https://example.com/'), true);
t.equal(await global.Scratch.canRedirect('index.html'), true);
t.equal(await global.Scratch.canRedirect(null), true);
t.equal(await api.Scratch.canRedirect('data:text/html,test'), true);
t.equal(await api.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), true);
t.equal(await api.Scratch.canRedirect('file:///etc/hosts'), true);
t.equal(await api.Scratch.canRedirect('https://example.com/'), true);
t.equal(await api.Scratch.canRedirect('index.html'), true);
t.equal(await api.Scratch.canRedirect(null), true);

const calledWithURLs = [];
vm.securityManager.canRedirect = async url => {
calledWithURLs.push(url);
return url === 'file:///etc/hosts';
};
t.equal(await global.Scratch.canRedirect('data:text/html,test'), false);
t.equal(await global.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await global.Scratch.canRedirect('file:///etc/hosts'), true);
t.equal(await global.Scratch.canRedirect('https://example.com/'), false);
t.equal(await global.Scratch.canRedirect('index.html'), false);
t.equal(await global.Scratch.canRedirect(null), false);
t.equal(await api.Scratch.canRedirect('data:text/html,test'), false);
t.equal(await api.Scratch.canRedirect('blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd'), false);
t.equal(await api.Scratch.canRedirect('file:///etc/hosts'), true);
t.equal(await api.Scratch.canRedirect('https://example.com/'), false);
t.equal(await api.Scratch.canRedirect('index.html'), false);
t.equal(await api.Scratch.canRedirect(null), false);
t.same(calledWithURLs, [
'data:text/html,test',
'blob:https://example.com/8c071bf8-c0b6-4a48-81d7-6413c2adf3dd',
Expand Down
44 changes: 20 additions & 24 deletions test/unit/tw_extension_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,53 +27,49 @@ test('_isValidExtensionURL', t => {
test('loadExtensionURL, getExtensionURLs, deduplication', async t => {
const vm = new VM();

let loadedExtensions = 0;
vm.extensionManager.securityManager.getSandboxMode = () => 'unsandboxed';
global.document = {
createElement: () => {
loadedExtensions++;
const element = {};
setTimeout(() => {
global.Scratch.extensions.register({
getInfo: () => ({
id: `extension${loadedExtensions}`
})
});

global.loadedExtensionCount = 0;
global.fetch = () => Promise.resolve({
ok: true,
text: () => Promise.resolve(`
const id = ++global.loadedExtensionCount;
Scratch.extensions.register({
getInfo: () => ({
id: "testextension" + id
}),
blocks: []
});
return element;
},
body: {
appendChild: () => {}
}
};
`)
});

const url1 = 'https://turbowarp.org/1.js';
t.equal(vm.extensionManager.isExtensionURLLoaded(url1), false);
t.same(vm.extensionManager.getExtensionURLs(), {});
await vm.extensionManager.loadExtensionURL(url1);
t.equal(vm.extensionManager.isExtensionURLLoaded(url1), true);
t.equal(loadedExtensions, 1);
t.equal(global.loadedExtensionCount, 1);
t.same(vm.extensionManager.getExtensionURLs(), {
extension1: url1
testextension1: url1
});

// Loading the extension again should do nothing.
await vm.extensionManager.loadExtensionURL(url1);
t.equal(vm.extensionManager.isExtensionURLLoaded(url1), true);
t.equal(loadedExtensions, 1);
t.equal(global.loadedExtensionCount, 1);
t.same(vm.extensionManager.getExtensionURLs(), {
extension1: url1
testextension1: url1
});

// Loading another extension should work
const url2 = 'https://turbowarp.org/2.js';
t.equal(vm.extensionManager.isExtensionURLLoaded(url2), false);
await vm.extensionManager.loadExtensionURL(url2);
t.equal(vm.extensionManager.isExtensionURLLoaded(url2), true);
t.equal(loadedExtensions, 2);
t.equal(global.loadedExtensionCount, 2);
t.same(vm.extensionManager.getExtensionURLs(), {
extension1: url1,
extension2: url2
testextension1: url1,
testextension2: url2
});

t.end();
Expand Down

0 comments on commit 6836209

Please sign in to comment.