Skip to content
This repository was archived by the owner on Apr 29, 2020. It is now read-only.

fix: validate rabin args #32

Merged
merged 3 commits into from
Jun 6, 2019
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: 16 additions & 0 deletions src/chunker/rabin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const BufferList = require('bl')
const { create } = require('rabin-wasm')
const errcode = require('err-code')

module.exports = async function * rabinChunker (source, options) {
const rabin = jsRabin()
Expand All @@ -12,12 +13,27 @@ module.exports = async function * rabinChunker (source, options) {
avg = options.avgChunkSize
min = options.minChunkSize
max = options.maxChunkSize
} else if (!options.avgChunkSize) {
throw errcode(new Error('please specify an average chunk size'), 'ERR_INVALID_AVG_CHUNK_SIZE')
} else {
avg = options.avgChunkSize
min = avg / 3
max = avg + (avg / 2)
}

// validate min/max/avg in the same way as go
if (min < 16) {
throw errcode(new Error('rabin min must be greater than 16'), 'ERR_INVALID_MIN_CHUNK_SIZE')
}

if (max < min) {
max = min
}

if (avg < min) {
avg = min
}

const sizepow = Math.floor(Math.log2(avg))

for await (const chunk of rabin(source, {
Expand Down
51 changes: 50 additions & 1 deletion test/chunker-rabin.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('chunker: rabin', function () {
const chunks = await all(chunker([b1], {
...defaultOptions,
maxChunkSize: 262144,
minChunkSize: 1,
minChunkSize: 18,
avgChunkSize: 256
}))

Expand All @@ -83,4 +83,53 @@ describe('chunker: rabin', function () {
expect(chunk).to.have.length.lte(opts.maxChunkSize)
})
})

it('throws when min chunk size is too small', async () => {
const opts = {
...defaultOptions,
minChunkSize: 1,
maxChunkSize: 100
}

try {
await all(chunker([], opts))
throw new Error('Should have thrown')
} catch (err) {
expect(err.code).to.equal('ERR_INVALID_MIN_CHUNK_SIZE')
}
})

it('throws when avg chunk size is not specified', async () => {
const opts = {
...defaultOptions,
avgChunkSize: undefined
}

try {
await all(chunker([], opts))
throw new Error('Should have thrown')
} catch (err) {
expect(err.code).to.equal('ERR_INVALID_AVG_CHUNK_SIZE')
}
})

it('uses the min chunk size when max and avg are too small', async () => {
let file = Buffer.concat([rawFile, Buffer.from('hello')])
const opts = {
...defaultOptions,
minChunkSize: 100,
maxChunkSize: 5,
avgChunkSize: 5
}

const chunks = await all(chunker([file], opts))

chunks.forEach((chunk, index) => {
if (index === chunks.length - 1) {
expect(chunk.length).to.equal(81)
} else {
expect(chunk.length).to.equal(100)
}
})
})
})