Skip to content
This repository was archived by the owner on Aug 24, 2021. It is now read-only.

Commit b5dbaca

Browse files
authored
fix: replace node buffers with uint8arrays (#92)
Removes node `Buffer`s in favour of `Uint8Array`s. BREAKING CHANGE: - Where node `Buffer`s were returned, now `Uint8Array`s are
1 parent b90be95 commit b5dbaca

File tree

4 files changed

+52
-77
lines changed

4 files changed

+52
-77
lines changed

README.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
js-multihash
2-
============
1+
# js-multihash <!-- omit in toc -->
32

43
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
54
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)
@@ -17,18 +16,18 @@ It is extended by [js-multihashing](https://github.com/multiformats/js-multihash
1716
and [js-multihashing-async](https://github.com/multiformats/js-multihashing-async),
1817
so give those a look as well.
1918

20-
## Lead Maintainer
19+
## Lead Maintainer <!-- omit in toc -->
2120

2221
[Hugo Dias](http://github.com/hugomrdias/)
2322

24-
## Table of Contents
23+
## Table of Contents <!-- omit in toc -->
2524

2625
- [Install](#install)
27-
- [In Node.js through npm](#in-nodejs-through-npm)
28-
- [Browser: Browserify, Webpack, other bundlers](#browser-browserify-webpack-other-bundlers)
29-
- [In the Browser through `<script>` tag](#in-the-browser-through-script-tag)
26+
- [Using npm](#using-npm)
27+
- [Using a `<script>` tag](#using-a-script-tag)
3028
- [Usage](#usage)
3129
- [API](#api)
30+
- [Update Constants](#update-constants)
3231
- [Contribute](#contribute)
3332
- [License](#license)
3433

@@ -60,17 +59,17 @@ Loading this module through a script tag will make the ```Multihashes``` obj ava
6059

6160
```js
6261
> var multihash = require('multihashes')
63-
> var buf = new Buffer('0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33', 'hex')
62+
> var bytes = Uint8Array.from([0, 1, 2, 3...])
6463

65-
> var encoded = multihash.encode(buf, 'sha1')
64+
> var encoded = multihash.encode(bytes, 'sha1')
6665
> console.log(encoded)
67-
<Buffer 11 14 0b ee c7 b5 ea 3f 0f db c9 5d 0d d4 7f 3c 5b c2 75 da 8a 33>
66+
<Uint8Array 11 14 0b ee c7 b5 ea 3f 0f db c9 5d 0d d4 7f 3c 5b c2 75 da 8a 33>
6867

6968
> multihash.decode(encoded)
7069
{ code: 17,
7170
name: 'sha1',
7271
length: 20,
73-
digest: <Buffer 0b ee c7 b5 ea 3f 0f db c9 5d 0d d4 7f 3c 5b c2 75 da 8a 33> }
72+
digest: <Uint8Array 0b ee c7 b5 ea 3f 0f db c9 5d 0d d4 7f 3c 5b c2 75 da 8a 33> }
7473
```
7574

7675
## API

package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,12 @@
3131
"main": "src/index.js",
3232
"repository": "github:multiformats/js-multihash",
3333
"dependencies": {
34-
"buffer": "^5.6.0",
35-
"multibase": "^2.0.0",
36-
"varint": "^5.0.0",
37-
"web-encoding": "^1.0.2"
34+
"multibase": "^3.0.0",
35+
"uint8arrays": "^1.0.0",
36+
"varint": "^5.0.0"
3837
},
3938
"devDependencies": {
40-
"aegir": "^24.0.0",
41-
"chai": "^4.1.2",
42-
"dirty-chai": "^2.0.1",
39+
"aegir": "^25.0.0",
4340
"ipfs-utils": "^2.3.1"
4441
},
4542
"contributors": [

src/index.js

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
*/
88
'use strict'
99

10-
const { Buffer } = require('buffer')
1110
const multibase = require('multibase')
1211
const varint = require('varint')
1312
const { names } = require('./constants')
14-
const { TextDecoder } = require('web-encoding')
13+
const uint8ArrayToString = require('uint8arrays/to-string')
14+
const uint8ArrayFromString = require('uint8arrays/from-string')
15+
const uint8ArrayConcat = require('uint8arrays/concat')
1516

1617
const textDecoder = new TextDecoder()
1718
const codes = {}
@@ -33,21 +34,17 @@ exports.toHexString = function toHexString (hash) {
3334
throw new Error('must be passed a Uint8Array')
3435
}
3536

36-
const buffer = Buffer.isBuffer(hash)
37-
? hash
38-
: Buffer.from(hash.buffer, hash.byteOffset, hash.byteLength)
39-
40-
return buffer.toString('hex')
37+
return uint8ArrayToString(hash, 'base16')
4138
}
4239

4340
/**
4441
* Convert the given hex encoded string to a multihash.
4542
*
4643
* @param {string} hash
47-
* @returns {Buffer}
44+
* @returns {Uint8Array}
4845
*/
4946
exports.fromHexString = function fromHexString (hash) {
50-
return Buffer.from(hash, 'hex')
47+
return uint8ArrayFromString(hash, 'base16')
5148
}
5249

5350
/**
@@ -68,7 +65,7 @@ exports.toB58String = function toB58String (hash) {
6865
* Convert the given base58 encoded string to a multihash.
6966
*
7067
* @param {string|Uint8Array} hash
71-
* @returns {Buffer}
68+
* @returns {Uint8Array}
7269
*/
7370
exports.fromB58String = function fromB58String (hash) {
7471
const encoded = hash instanceof Uint8Array
@@ -82,41 +79,38 @@ exports.fromB58String = function fromB58String (hash) {
8279
* Decode a hash from the given multihash.
8380
*
8481
* @param {Uint8Array} bytes
85-
* @returns {{code: number, name: string, length: number, digest: Buffer}} result
82+
* @returns {{code: number, name: string, length: number, digest: Uint8Array}} result
8683
*/
8784
exports.decode = function decode (bytes) {
8885
if (!(bytes instanceof Uint8Array)) {
8986
throw new Error('multihash must be a Uint8Array')
9087
}
91-
let buf = Buffer.isBuffer(bytes)
92-
? bytes
93-
: Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)
9488

95-
if (buf.length < 2) {
89+
if (bytes.length < 2) {
9690
throw new Error('multihash too short. must be > 2 bytes.')
9791
}
9892

99-
const code = varint.decode(buf)
93+
const code = varint.decode(bytes)
10094
if (!exports.isValidCode(code)) {
10195
throw new Error(`multihash unknown function code: 0x${code.toString(16)}`)
10296
}
103-
buf = buf.slice(varint.decode.bytes)
97+
bytes = bytes.slice(varint.decode.bytes)
10498

105-
const len = varint.decode(buf)
99+
const len = varint.decode(bytes)
106100
if (len < 0) {
107101
throw new Error(`multihash invalid length: ${len}`)
108102
}
109-
buf = buf.slice(varint.decode.bytes)
103+
bytes = bytes.slice(varint.decode.bytes)
110104

111-
if (buf.length !== len) {
112-
throw new Error(`multihash length inconsistent: 0x${buf.toString('hex')}`)
105+
if (bytes.length !== len) {
106+
throw new Error(`multihash length inconsistent: 0x${uint8ArrayToString(bytes, 'base16')}`)
113107
}
114108

115109
return {
116110
code,
117111
name: codes[code],
118112
length: len,
119-
digest: buf
113+
digest: bytes
120114
}
121115
}
122116

@@ -128,7 +122,7 @@ exports.decode = function decode (bytes) {
128122
* @param {Uint8Array} digest
129123
* @param {string|number} code
130124
* @param {number} [length]
131-
* @returns {Buffer}
125+
* @returns {Uint8Array}
132126
*/
133127
exports.encode = function encode (digest, code, length) {
134128
if (!digest || code === undefined) {
@@ -152,11 +146,7 @@ exports.encode = function encode (digest, code, length) {
152146

153147
const hash = varint.encode(hashfn)
154148
const len = varint.encode(length)
155-
const buffer = Buffer.alloc(hash.length + len.length + digest.length)
156-
buffer.set(hash, 0)
157-
buffer.set(len, hash.length)
158-
buffer.set(digest, hash.length + len.length)
159-
return buffer
149+
return uint8ArrayConcat([hash, len, digest], hash.length + len.length + digest.length)
160150
}
161151

162152
/**
@@ -230,11 +220,11 @@ exports.validate = validate
230220
* Returns a prefix from a valid multihash. Throws an error if it is not valid.
231221
*
232222
* @param {Uint8Array} multihash
233-
* @returns {Buffer}
223+
* @returns {Uint8Array}
234224
* @throws {Error}
235225
*/
236226
exports.prefix = function prefix (multihash) {
237227
validate(multihash)
238228

239-
return Buffer.from(multihash.buffer, multihash.byteOffset, 2)
229+
return multihash.subarray(0, 2)
240230
}

test/index.spec.js

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22
/* eslint max-nested-callbacks: off */
33
'use strict'
44

5-
const chai = require('chai')
6-
const dirtyChai = require('dirty-chai')
7-
chai.use(dirtyChai)
8-
const expect = chai.expect
5+
const { expect } = require('aegir/utils/chai')
96
const multibase = require('multibase')
10-
const { Buffer } = require('buffer')
117
const mh = require('../src')
128
const constants = require('../src/constants')
139
const validCases = require('./fixtures/valid')
1410
const invalidCases = require('./fixtures/invalid')
15-
const { TextEncoder } = require('web-encoding')
11+
const uint8ArrayToString = require('uint8arrays/to-string')
12+
const uint8ArrayFromString = require('uint8arrays/from-string')
13+
const uint8ArrayEquals = require('uint8arrays/equals')
1614

1715
function sample (code, size, hex) {
1816
const toHex = (i) => {
@@ -22,22 +20,13 @@ function sample (code, size, hex) {
2220
const h = i.toString(16)
2321
return h.length % 2 === 1 ? `0${h}` : h
2422
}
25-
return Buffer.from(`${toHex(code)}${toHex(size)}${hex}`, 'hex')
23+
return uint8ArrayFromString(`${toHex(code)}${toHex(size)}${hex}`, 'base16')
2624
}
2725

2826
const they = (description, test) => {
29-
it(`${description} (Buffer)`, () => test({
30-
encodeText: Buffer.from,
31-
encodeHex: (text) => Buffer.from(text, 'hex')
32-
}))
33-
34-
const textEncoder = new TextEncoder()
35-
it(`${description} (Uint8Array)`, () => test({
36-
encodeText: (text) => textEncoder.encode(text),
37-
encodeHex: (text) => {
38-
const { buffer, byteOffset, byteLength } = Buffer.from(text, 'hex')
39-
return new Uint8Array(buffer, byteOffset, byteLength)
40-
}
27+
it(description, () => test({
28+
encodeText: (text) => uint8ArrayFromString(text),
29+
encodeHex: (text) => uint8ArrayFromString(text, 'base16')
4130
}))
4231
}
4332

@@ -50,7 +39,7 @@ describe('multihash', () => {
5039
expect(
5140
mh.toHexString(buf)
5241
).to.be.eql(
53-
buf.toString('hex')
42+
uint8ArrayToString(buf, 'base16')
5443
)
5544
})
5645
})
@@ -70,9 +59,9 @@ describe('multihash', () => {
7059
const code = test.encoding.code
7160
const buf = mh.encode(encodeHex(test.hex), code)
7261
expect(
73-
mh.fromHexString(buf.toString('hex')).toString('hex')
62+
uint8ArrayToString(mh.fromHexString(uint8ArrayToString(buf, 'base16')), 'base16')
7463
).to.be.eql(
75-
buf.toString('hex')
64+
uint8ArrayToString(buf, 'base16')
7665
)
7766
})
7867
})
@@ -86,7 +75,7 @@ describe('multihash', () => {
8675
expect(
8776
mh.toB58String(buf)
8877
).to.be.eql(
89-
multibase.encode('base58btc', buf).toString().slice(1)
78+
uint8ArrayToString(multibase.encode('base58btc', buf)).slice(1)
9079
)
9180
})
9281
})
@@ -125,7 +114,7 @@ describe('multihash', () => {
125114
const code = test.encoding.code
126115
const buf = sample(test.encoding.varint || code, test.size, test.hex)
127116
const name = test.encoding.name
128-
const d1 = Buffer.from(test.hex, 'hex')
117+
const d1 = uint8ArrayFromString(test.hex, 'base16')
129118
const length = d1.length
130119

131120
const r = mh.decode(buf)
@@ -134,7 +123,7 @@ describe('multihash', () => {
134123
expect(r.code).to.equal(code)
135124
expect(r.name).to.equal(name)
136125
expect(r.length).to.equal(length)
137-
expect(d1.equals(d2)).to.equal(true)
126+
expect(uint8ArrayEquals(d1, d2)).to.equal(true)
138127
})
139128
})
140129

@@ -160,9 +149,9 @@ describe('multihash', () => {
160149

161150
results.forEach((res) => {
162151
expect(
163-
res.toString('hex')
152+
uint8ArrayToString(res, 'base16')
164153
).to.be.eql(
165-
buf.toString('hex')
154+
uint8ArrayToString(buf, 'base16')
166155
)
167156
})
168157
})
@@ -205,7 +194,7 @@ describe('multihash', () => {
205194
).to.throw()
206195
})
207196

208-
const longBuffer = Uint8Array.from(Buffer.alloc(150, 'a'))
197+
const longBuffer = new Uint8Array(150).fill(0)
209198
expect(
210199
() => mh.validate(longBuffer)
211200
).to.throw()
@@ -326,7 +315,7 @@ describe('multihash', () => {
326315
they('prefix', ({ encodeText }) => {
327316
const multihash = mh.encode(encodeText('hey'), 0x11, 3)
328317
const prefix = mh.prefix(multihash)
329-
expect(prefix.toString('hex')).to.eql('1103')
318+
expect(uint8ArrayToString(prefix, 'base16')).to.eql('1103')
330319
})
331320

332321
they('prefix throws on invalid multihash', ({ encodeText }) => {

0 commit comments

Comments
 (0)