Skip to content

Commit 156911e

Browse files
mkg20001daviddias
authored andcommitted
fix: catch error when unmarshaling instead of crashing (#72)
1 parent f91f2b6 commit 156911e

File tree

4 files changed

+64
-19
lines changed

4 files changed

+64
-19
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
docs
12
**/node_modules/
23
**/*.log
34
test/repo-tests*
@@ -41,4 +42,4 @@ test/test-data/go-ipfs-repo/LOG.old
4142

4243
# while testing npm5
4344
package-lock.json
44-
yarn.lock
45+
yarn.lock

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@
3333
},
3434
"homepage": "https://github.com/libp2p/js-peer-id",
3535
"devDependencies": {
36-
"aegir": "^12.0.8",
36+
"aegir": "^12.2.0",
3737
"chai": "^4.1.2",
3838
"dirty-chai": "^2.0.1",
3939
"pre-commit": "^1.2.2"
4040
},
4141
"dependencies": {
42-
"async": "^2.5.0",
43-
"libp2p-crypto": "~0.10.3",
42+
"async": "^2.6.0",
43+
"libp2p-crypto": "~0.10.4",
4444
"lodash": "^4.17.4",
45-
"multihashes": "~0.4.9"
45+
"multihashes": "~0.4.12"
4646
},
4747
"repository": {
4848
"type": "git",

src/index.js

+38-14
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,20 @@ exports.createFromPubKey = function (key, callback) {
165165
throw new Error('callback is required')
166166
}
167167

168-
let buf = key
169-
if (typeof buf === 'string') {
170-
buf = Buffer.from(key, 'base64')
171-
}
168+
let pubKey
169+
170+
try {
171+
let buf = key
172+
if (typeof buf === 'string') {
173+
buf = Buffer.from(key, 'base64')
174+
}
172175

173-
const pubKey = crypto.keys.unmarshalPublicKey(buf)
176+
if (!Buffer.isBuffer(buf)) throw new Error('Supplied key is neither a base64 string nor a buffer')
177+
178+
pubKey = crypto.keys.unmarshalPublicKey(buf)
179+
} catch (err) {
180+
return callback(err)
181+
}
174182

175183
pubKey.hash((err, digest) => {
176184
if (err) {
@@ -183,15 +191,22 @@ exports.createFromPubKey = function (key, callback) {
183191

184192
// Private key input will be a string
185193
exports.createFromPrivKey = function (key, callback) {
186-
let buf = key
187-
if (typeof buf === 'string') {
188-
buf = Buffer.from(key, 'base64')
189-
}
190-
191194
if (typeof callback !== 'function') {
192195
throw new Error('callback is required')
193196
}
194197

198+
let buf = key
199+
200+
try {
201+
if (typeof buf === 'string') {
202+
buf = Buffer.from(key, 'base64')
203+
}
204+
205+
if (!Buffer.isBuffer(buf)) throw new Error('Supplied key is neither a base64 string nor a buffer')
206+
} catch (err) {
207+
return callback(err)
208+
}
209+
195210
waterfall([
196211
(cb) => crypto.keys.unmarshalPrivateKey(buf, cb),
197212
(privKey, cb) => privKey.public.hash((err, digest) => {
@@ -211,10 +226,19 @@ exports.createFromJSON = function (obj, callback) {
211226
throw new Error('callback is required')
212227
}
213228

214-
const id = mh.fromB58String(obj.id)
215-
const rawPrivKey = obj.privKey && Buffer.from(obj.privKey, 'base64')
216-
const rawPubKey = obj.pubKey && Buffer.from(obj.pubKey, 'base64')
217-
const pub = rawPubKey && crypto.keys.unmarshalPublicKey(rawPubKey)
229+
let id
230+
let rawPrivKey
231+
let rawPubKey
232+
let pub
233+
234+
try {
235+
id = mh.fromB58String(obj.id)
236+
rawPrivKey = obj.privKey && Buffer.from(obj.privKey, 'base64')
237+
rawPubKey = obj.pubKey && Buffer.from(obj.pubKey, 'base64')
238+
pub = rawPubKey && crypto.keys.unmarshalPublicKey(rawPubKey)
239+
} catch (err) {
240+
return callback(err)
241+
}
218242

219243
if (rawPrivKey) {
220244
waterfall([

test/peer-id.spec.js

+20
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const parallel = require('async/parallel')
1212

1313
const PeerId = require('../src')
1414

15+
const util = require('util')
16+
1517
const testId = require('./fixtures/sample-id')
1618
const testIdHex = testId.id
1719
const testIdBytes = mh.fromHexString(testId.id)
@@ -245,6 +247,24 @@ describe('PeerId', () => {
245247
})
246248
})
247249

250+
describe('returns error via cb instead of crashing', () => {
251+
const garbage = [Buffer.from('00010203040506070809', 'hex'), {}, null, false, undefined, true, 1, 0, Buffer.from(''), 'aGVsbG93b3JsZA==', 'helloworld', '']
252+
253+
const fncs = ['createFromPubKey', 'createFromPrivKey', 'createFromJSON']
254+
255+
garbage.forEach(garbage => {
256+
fncs.forEach(fnc => {
257+
it(fnc + '(' + util.inspect(garbage) + ')', cb => {
258+
PeerId[fnc](garbage, (err, res) => {
259+
expect(err).to.exist()
260+
expect(res).to.not.exist()
261+
cb()
262+
})
263+
})
264+
})
265+
})
266+
})
267+
248268
describe('throws on inconsistent data', () => {
249269
let k1
250270
let k2

0 commit comments

Comments
 (0)