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

fix: replace node buffers with uint8arrays #134

Merged
merged 3 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# js-ipld-dag-cbor
# js-ipld-dag-cbor <!-- omit in toc -->

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-IPLD-blue.svg?style=flat-square)](http://github.com/ipld/ipld)
Expand All @@ -14,11 +14,11 @@

> JavaScript implementation of the [IPLD spec](https://github.com/ipfs/specs/tree/master/ipld).

## Lead Maintainer
## Lead Maintainer <!-- omit in toc -->

[Volker Mische](https://github.com/vmx)

## Table of Contents
## Table of Contents <!-- omit in toc -->

- [Install](#install)
- [npm](#npm)
Expand All @@ -27,6 +27,10 @@
- [Use in a browser Using a script tag](#use-in-a-browser-using-a-script-tag)
- [Usage](#usage)
- [API](#api)
- [`dagCBOR.util.serialize(obj)`](#dagcborutilserializeobj)
- [`dagCBOR.util.deserialize(serialized)`](#dagcborutildeserializeserialized)
- [`dagCBOR.util.configureDecoder([options])`](#dagcborutilconfiguredecoderoptions)
- [`dagCBOR.util.cid(obj[, options,])`](#dagcborutilcidobj-options)
- [Contribute](#contribute)
- [License](#license)

Expand Down Expand Up @@ -73,13 +77,13 @@ const file = {
}

const serialized = dagCBOR.util.serialize(file)
console.log(`Encoded as a ${serialized.length} byte Buffer`)
console.log(`Encoded as a ${serialized.length} byte Uint8Array`)

const node = dagCBOR.util.deserialize(serialized)
console.log('Decoded as:', node)
require('assert').deepEqual(node, file) // should match

// → Encoded as a 22 byte Buffer
// → Encoded as a 22 byte Uint8Array
// → Decoded as: { name: 'hello.txt', size: 11 }
```

Expand All @@ -97,7 +101,7 @@ Returns the serialized node.

Decodes an IPLD CBOR encoded representation, restoring any CBOR tags (id `42`) to CIDs.

- `serialized` (`Buffer` or `String`): a binary blob representing an IPLD CBOR encoded object.
- `serialized` (`Uint8Array` or `String`): a binary blob representing an IPLD CBOR encoded object.

Returns the deserialized object.

Expand Down
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,17 @@
"homepage": "https://github.com/ipld/js-ipld-dag-cbor",
"dependencies": {
"borc": "^2.1.2",
"buffer": "^5.6.0",
"cids": "~0.8.3",
"cids": "^1.0.0",
"is-circular": "^1.0.2",
"multicodec": "^1.0.3",
"multihashing-async": "^1.0.0"
"multicodec": "^2.0.0",
"multihashing-async": "^2.0.0",
"uint8arrays": "^1.0.0"
},
"devDependencies": {
"aegir": "^25.0.0",
"chai": "^4.2.0",
"detect-node": "^2.0.4",
"dirty-chai": "^2.0.1",
"garbage": "0.0.0",
"multihashes": "^1.0.1"
"multihashes": "^3.0.1"
},
"contributors": [
"David Dias <daviddias.p@gmail.com>",
Expand Down
7 changes: 3 additions & 4 deletions src/resolver.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const CID = require('cids')
const { Buffer } = require('buffer')
const util = require('./util')

/**
Expand All @@ -10,7 +9,7 @@ const util = require('./util')
* Returns the value or a link and the partial mising path. This way the
* IPLD Resolver can fetch the link and continue to resolve.
*
* @param {Buffer} binaryBlob - Binary representation of a CBOR block
* @param {Uint8Array} binaryBlob - Binary representation of a CBOR block
* @param {string} [path='/'] - Path that should be resolved
* @returns {Object} result - Result of the path it it was resolved successfully
* @returns {*} result.value - Value the path resolves to
Expand Down Expand Up @@ -45,7 +44,7 @@ exports.resolve = (binaryBlob, path) => {

const traverse = function * (node, path) {
// Traverse only objects and arrays
if (Buffer.isBuffer(node) || CID.isCID(node) || typeof node === 'string' ||
if (node instanceof Uint8Array || CID.isCID(node) || typeof node === 'string' ||
node === null) {
return
}
Expand All @@ -60,7 +59,7 @@ const traverse = function * (node, path) {
* Return all available paths of a block.
*
* @generator
* @param {Buffer} binaryBlob - Binary representation of a CBOR block
* @param {Uint8Array} binaryBlob - Binary representation of a CBOR block
* @yields {string} - A single path
*/
exports.tree = function * (binaryBlob) {
Expand Down
17 changes: 9 additions & 8 deletions src/util.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
'use strict'

const cbor = require('borc')
const { Buffer } = require('buffer')
const multicodec = require('multicodec')
const multihashing = require('multihashing-async')
const CID = require('cids')
const isCircular = require('is-circular')
const uint8ArrayConcat = require('uint8arrays/concat')
const uint8ArrayFromString = require('uint8arrays/from-string')

// https://github.com/ipfs/go-ipfs/issues/3570#issuecomment-273931692
const CID_CBOR_TAG = 42

function tagCID (cid) {
if (typeof cid === 'string') {
cid = new CID(cid).buffer
cid = new CID(cid).bytes
} else if (CID.isCID(cid)) {
cid = cid.buffer
cid = cid.bytes
}

return new cbor.Tagged(CID_CBOR_TAG, Buffer.concat([
Buffer.from('00', 'hex'), // thanks jdag
return new cbor.Tagged(CID_CBOR_TAG, uint8ArrayConcat([
uint8ArrayFromString('00', 'base16'), // thanks jdag
cid
]))
], 1 + cid.length))
}

function replaceCIDbyTAG (dagNode) {
Expand Down Expand Up @@ -129,7 +130,7 @@ exports.configureDecoder() // Setup default cbor.Decoder
* Serialize internal representation into a binary CBOR block.
*
* @param {Object} node - Internal representation of a CBOR block
* @returns {Buffer} - The encoded binary representation
* @returns {Uint8Array} - The encoded binary representation
*/
exports.serialize = (node) => {
const nodeTagged = replaceCIDbyTAG(node)
Expand All @@ -141,7 +142,7 @@ exports.serialize = (node) => {
/**
* Deserialize CBOR block into the internal representation.
*
* @param {Buffer} data - Binary representation of a CBOR block
* @param {Uint8Array} data - Binary representation of a CBOR block
* @returns {Object} - An object that conforms to the IPLD Data Model
*/
exports.deserialize = (data) => {
Expand Down
5 changes: 1 addition & 4 deletions test/interop.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const { expect } = require('aegir/utils/chai')
const dagCBOR = require('../src')
const loadFixture = require('aegir/fixtures')
const isNode = require('detect-node')
Expand Down
6 changes: 1 addition & 5 deletions test/mod.spec.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const { expect } = require('aegir/utils/chai')
const multicodec = require('multicodec')

const mod = require('../src')

describe('IPLD Format', () => {
Expand Down
7 changes: 1 addition & 6 deletions test/resolver.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
/* eslint max-nested-callbacks: ["error", 5] */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)

const { expect } = require('aegir/utils/chai')
const CID = require('cids')

const dagCBOR = require('../src')
const resolver = dagCBOR.resolver

Expand Down
18 changes: 8 additions & 10 deletions test/util.spec.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
/* eslint-env mocha */
'use strict'

const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const { expect } = require('aegir/utils/chai')
const garbage = require('garbage')
const dagCBOR = require('../src')
const multihash = require('multihashes')
const CID = require('cids')
const uint8ArrayFromString = require('uint8arrays/from-string')
const uint8ArrayConcat = require('uint8arrays/concat')

describe('util', () => {
const obj = {
Expand All @@ -27,7 +25,7 @@ describe('util', () => {
const serializedObj = dagCBOR.util.serialize(obj)

it('.serialize and .deserialize', () => {
expect(Buffer.isBuffer(serializedObj)).to.equal(true)
expect(serializedObj).to.be.a('Uint8Array')

// Check for the tag 42
// d8 = tag, 2a = 42
Expand All @@ -45,7 +43,7 @@ describe('util', () => {
const largeObj = { someKey: [].slice.call(new Uint8Array(dataSize)) }

const serialized = dagCBOR.util.serialize(largeObj)
expect(Buffer.isBuffer(serialized)).to.be.true()
expect(serialized).to.be.a('Uint8Array')

const deserialized = dagCBOR.util.deserialize(serialized)
expect(largeObj).to.eql(deserialized)
Expand All @@ -60,7 +58,7 @@ describe('util', () => {

dagCBOR.util.configureDecoder({ size: 64 * 1024, maxSize: 128 * 1024 }) // 64 Kb start, 128 Kb max
const serialized = dagCBOR.util.serialize(largeObj)
expect(Buffer.isBuffer(serialized)).to.be.true()
expect(serialized).to.be.a('Uint8Array')

expect(() => dagCBOR.util.deserialize(serialized)).to.throw(
'Data is too large to deserialize with current decoder')
Expand Down Expand Up @@ -111,7 +109,7 @@ describe('util', () => {
})

it('.serialize and .deserialize object with Uint8Array field', () => {
const buffer = Buffer.from('some data')
const buffer = uint8ArrayFromString('some data')
const bytes = Uint8Array.from(buffer)

const s1 = dagCBOR.util.serialize({ data: buffer })
Expand All @@ -127,7 +125,7 @@ describe('util', () => {
expect(() =>
// two top-level CBOR objects, the original and a single uint=0, valid if using
// CBOR in streaming mode, not valid here
dagCBOR.util.deserialize(Buffer.concat([serializedObj, Buffer.alloc(1)]))
dagCBOR.util.deserialize(uint8ArrayConcat([serializedObj, new Uint8Array(1)]))
).to.throw(Error, 'Extraneous CBOR data found beyond initial top-level object')
})
})