Skip to content

Commit 1c10226

Browse files
committed
prevent bad link in opstream from crashing sidecar
1 parent b9fe9ce commit 1c10226

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

subsystems/sidecar/lib/opstream.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22
const streamx = require('streamx')
33
const plink = require('pear-link')
4+
const { ERR_INVALID_LINK } = require('pear-errors')
45
const Session = require('./session')
56
module.exports = class Opstream extends streamx.Readable {
67
final = {}
@@ -24,7 +25,15 @@ module.exports = class Opstream extends streamx.Readable {
2425
if (autosession) return this.session.close()
2526
}
2627

27-
if (params.link) params.link = plink.normalize(params.link)
28+
if (params.link !== undefined) {
29+
try {
30+
params.link = plink.normalize(params.link)
31+
} catch (e) {
32+
e.code = ERR_INVALID_LINK.name
33+
error(e)
34+
return close()
35+
}
36+
}
2837
op(params).catch(error).finally(close)
2938
}
3039
})

test/15-opstream.test.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
const test = require('brittle')
2+
const b4a = require('b4a')
3+
4+
const Helper = require('./helper')
5+
const { ERR_INVALID_LINK } = require('pear-errors')
6+
7+
const opMethods = [
8+
'data',
9+
'drop',
10+
'dump',
11+
'gc',
12+
'info',
13+
'release',
14+
'run',
15+
'seed',
16+
'shift',
17+
'stage',
18+
'touch'
19+
]
20+
21+
const testOp = async ({ t, link, helper, method, checkError } = opts) => {
22+
const stream = helper[method]({ link })
23+
try {
24+
await Helper.pick(stream, { tag: 'final' })
25+
t.fail('expected op to fail (op passed)')
26+
} catch (e) {
27+
if (checkError(e)) {
28+
t.pass()
29+
} else {
30+
t.fail(`op failed with unexepcted error: ${e}`)
31+
}
32+
}
33+
}
34+
35+
test('running ops with invalid link param type does not crash the sidecar', async (t) => {
36+
const links = [
37+
{},
38+
{ id: 'invalid-link' },
39+
0,
40+
1,
41+
null,
42+
true,
43+
false,
44+
b4a.allocUnsafe(8)
45+
]
46+
t.plan(opMethods.length * links.length * 2)
47+
48+
const helper = new Helper()
49+
t.teardown(() => helper.close(), { order: Infinity })
50+
await helper.ready()
51+
const checkError = (e) => e.code === ERR_INVALID_LINK.name
52+
53+
for (const method of opMethods) {
54+
for (const link of links) {
55+
t.comment(`calling "${method}" with link set to ${JSON.stringify(link)}`)
56+
await testOp({ t, link, helper, method, checkError })
57+
t.comment(`calling "${method}" again (testing sidecar not crashed)`)
58+
await testOp({ t, link, helper, method, checkError })
59+
}
60+
}
61+
})

test/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ async function runTests() {
2121
await import('./12-assets.test.js')
2222
await import('./13-stage.test.js')
2323
await import('./14-preflight.test.js')
24+
await import('./15-opstream.test.js')
2425

2526
test.resume()
2627
}

0 commit comments

Comments
 (0)