Skip to content

Commit

Permalink
test: eval internal tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 25, 2020
1 parent afc647a commit 41d8b2a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 6 deletions.
77 changes: 71 additions & 6 deletions packages/plugin-eval/tests/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { App } from 'koishi-test-utils'
import { inspect } from 'util'
import * as _eval from '../dist'
import { resolve } from 'path'
import * as _eval from 'koishi-plugin-eval'

const app = new App()
app.plugin(_eval)
app.plugin(_eval, {
setupFiles: {
'test-worker': resolve(__dirname, 'worker.js'),
},
})

const ses = app.createSession('user', 123)

Expand All @@ -30,8 +35,8 @@ describe('koishi-plugin-eval', () => {
})

it('exec', async () => {
await ses.shouldHaveReply('> exec()').which.matches(/TypeError: The "message" argument must be of type string/)
await ses.shouldHaveReply('> exec("help")').which.matches(//)
await ses.shouldHaveReply('> exec()').which.matches(/^TypeError: The "message" argument must be of type string/)
await ses.shouldHaveReply('> exec("help")').which.matches(/^/)
})

it('global', async () => {
Expand All @@ -44,10 +49,49 @@ describe('koishi-plugin-eval', () => {
await ses.shouldHaveReply('> Buffer.alloc.toString()', 'function alloc() { [native code] }')
})

it('contextify', async () => {
await ses.shouldHaveReply('> test.null === null', 'true')
await ses.shouldHaveReply('> test.undefined === undefined', 'true')
await ses.shouldHaveReply('> test.string.constructor === String', 'true')
await ses.shouldHaveReply('> test.number.constructor === Number', 'true')
await ses.shouldHaveReply('> test.boolean.constructor === Boolean', 'true')
await ses.shouldHaveReply('> test.stringO instanceof String', 'true')
await ses.shouldHaveReply('> test.numberO instanceof Number', 'true')
await ses.shouldHaveReply('> test.booleanO instanceof Boolean', 'true')
await ses.shouldHaveReply('> test.date instanceof Date', 'true')
await ses.shouldHaveReply('> test.regexp instanceof RegExp', 'true')
await ses.shouldHaveReply('> test.buffer instanceof Buffer', 'true')
await ses.shouldHaveReply('> test.error instanceof Error', 'true')
await ses.shouldHaveReply('> test.rangeError instanceof RangeError', 'true')
await ses.shouldHaveReply('> test.syntaxError instanceof SyntaxError', 'true')
await ses.shouldHaveReply('> test.referenceError instanceof ReferenceError', 'true')
await ses.shouldHaveReply('> test.typeError instanceof TypeError', 'true')
await ses.shouldHaveReply('> test.evalError instanceof EvalError', 'true')
await ses.shouldHaveReply('> test.uriError instanceof URIError', 'true')
})

it('function', async () => {
await ses.shouldHaveReply('> test.function instanceof Function', 'true')
await ses.shouldHaveReply('> test.function() instanceof Function', 'true')
await ses.shouldHaveReply('> test.function()() instanceof Object', 'true')
})

it('symbol', async () => {
await ses.shouldHaveReply('> Symbol.for("test") === test.symbol2', 'true')
await ses.shouldHaveReply('> test.symbol1.constructor.constructor === Function', 'true')
await ses.shouldHaveReply('> test.symbol2.constructor.constructor === Function', 'true')
await ses.shouldHaveReply('> test.symbol3.constructor.constructor === Function', 'true')
await ses.shouldHaveReply('> Symbol("test").constructor.constructor === Function', 'true')
await ses.shouldHaveReply('> Symbol("foobar").constructor.constructor === Function', 'true')
await ses.shouldHaveReply('> Symbol.keyFor(test.symbol2)', 'test')
})

it('host inspect', async () => {
await ses.shouldHaveReply('> [1, 2]', inspect([1, 2]))
await ses.shouldHaveReply('> new Set([1, 2])', inspect(new Set([1, 2])))
await ses.shouldHaveReply('> new Map([[1, 2]])', inspect(new Map([[1, 2]])))
await ses.shouldHaveReply('> new WeakSet([[1]])', inspect(new WeakSet([[1]])))
await ses.shouldHaveReply('> new WeakMap([[[1], 2]])', inspect(new WeakMap([[[1], 2]])))
await ses.shouldHaveReply('> new RegExp()', inspect(new RegExp(undefined)))
await ses.shouldHaveReply('> Proxy', inspect(Proxy))
})
Expand All @@ -62,10 +106,28 @@ describe('koishi-plugin-eval', () => {
await ses.shouldHaveReply(`>
const ForeignFunction = global.constructor.constructor;
const process1 = ForeignFunction("return process")();
`).which.matches(/ReferenceError: process is not defined/)
`).which.matches(/^ReferenceError: process is not defined/)
})

it('buffer attack', async () => {
it('deprecated api attack', async () => {
await ses.shouldHaveReply(`> Buffer.prototype.__defineGetter__ === {}.__defineGetter__`, 'true')
await ses.shouldHaveReply(`> Buffer.prototype.__defineSetter__ === {}.__defineSetter__`, 'true')
await ses.shouldHaveReply(`> Buffer.prototype.__lookupGetter__ === {}.__lookupGetter__`, 'true')
await ses.shouldHaveReply(`> Buffer.prototype.__lookupSetter__ === {}.__lookupSetter__`, 'true')

await ses
.shouldHaveReply(`> Buffer.prototype.__defineGetter__("toString", () => {})`)
.which.matches(/'defineProperty' on proxy: trap returned falsish for property 'toString'/)

await ses.shouldHaveReply(`>
global.__defineGetter__("foo", () => 123);
global.foo;
`, '123')

await ses.shouldHaveReply(`> Buffer.from.__lookupGetter__("__proto__") === Object.prototype.__lookupGetter__.call(Buffer.from, "__proto__")`, 'true')
})

it('buffer operations', async () => {
await ses.shouldHaveReply(`>
Buffer.allocUnsafe(100).constructor.constructor === Function &&
Buffer.allocUnsafeSlow(100).constructor.constructor === Function;
Expand All @@ -75,5 +137,8 @@ describe('koishi-plugin-eval', () => {
Buffer.allocUnsafe(100).toString('hex') +
Buffer.allocUnsafeSlow(100).toString('hex');
`, '00'.repeat(200))

await ses.shouldHaveReply('> test.buffer.inspect()', `<Buffer ${'01 '.repeat(50)}... 950 more bytes>`)
await ses.shouldHaveReply('> Buffer.from(Array(51).fill(1)).inspect()', `<Buffer ${'01 '.repeat(50)}... 1 more byte>`)
})
})
30 changes: 30 additions & 0 deletions packages/plugin-eval/tests/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-disable no-new-wrappers */

const { internal } = require('koishi-plugin-eval/dist/worker')

internal.setGlobal('test', {
null: null,
undefined: undefined,
string: 'text',
number: 1,
boolean: true,
stringO: new String('text'),
numberO: new Number(1),
booleanO: new Boolean(true),
date: new Date(),
regexp: /xxx/,
buffer: Buffer.from(Array(1000).fill(1)),
symbol1: Symbol('test'),
symbol2: Symbol.for('test'),
symbol3: Symbol.iterator,
error: new Error('test'),
rangeError: new RangeError('test'),
syntaxError: new SyntaxError('test'),
referenceError: new ReferenceError('test'),
typeError: new TypeError('test'),
evalError: new EvalError('test'),
uriError: new URIError('test'),
function() {
return () => ({})
},
})

0 comments on commit 41d8b2a

Please sign in to comment.