@ronomon/base64
Advanced tools
Comparing version 1.0.1 to 1.1.0
34
index.js
@@ -22,2 +22,3 @@ 'use strict'; | ||
var SILENT = 1; | ||
var SPECIAL = 1 << 24; | ||
@@ -87,3 +88,3 @@ var ILLEGAL = 1 << 25; | ||
function decode(source, target) { | ||
function decode(source, target, flags) { | ||
if (!Buffer.isBuffer(source)) { | ||
@@ -95,2 +96,10 @@ throw new Error('source must be a buffer'); | ||
} | ||
if ( | ||
typeof flags !== 'number' || | ||
Math.floor(flags) !== flags || | ||
flags < 0 || | ||
flags > 255 | ||
) { | ||
throw new Error('flags must be an 8-bit integer'); | ||
} | ||
var targetLength = target.length; | ||
@@ -105,3 +114,5 @@ var sourceLength = source.length; | ||
if (decode_table_3[source[sourceIndex]] & ILLEGAL) { | ||
throw new Error('source is corrupt'); | ||
if (!(flags & SILENT)) { | ||
throw new Error('source is corrupt'); | ||
} | ||
} | ||
@@ -146,3 +157,7 @@ sourceIndex++; | ||
if (word & SPECIAL) { | ||
if (word & ILLEGAL) throw new Error('source is corrupt'); | ||
if (word & ILLEGAL) { | ||
if (!(flags & SILENT)) { | ||
throw new Error('source is corrupt'); | ||
} | ||
} | ||
step(); | ||
@@ -160,3 +175,5 @@ } else { | ||
if (tempIndex === 1) { | ||
throw new Error('source is truncated'); | ||
if (!(flags & SILENT)) { | ||
throw new Error('source is truncated'); | ||
} | ||
} else if (tempIndex === 2) { | ||
@@ -260,2 +277,3 @@ word = ( | ||
var binding = self.binding.active; | ||
var flags = 0; | ||
if (options) { | ||
@@ -266,5 +284,11 @@ if (options.hasOwnProperty('binding')) { | ||
} | ||
if (options.hasOwnProperty('silent')) { | ||
if (options.silent !== true && options.silent !== false) { | ||
throw new Error('options.silent must be a boolean'); | ||
} | ||
if (options.silent) flags |= 1; | ||
} | ||
} | ||
var target = Buffer.alloc(Math.ceil(source.length / 4) * 3); | ||
var targetSize = binding.decode(source, target); | ||
var targetSize = binding.decode(source, target, flags); | ||
if (targetSize > target.length) throw new Error('target overflow'); | ||
@@ -271,0 +295,0 @@ return target.slice(0, targetSize); |
{ | ||
"name": "@ronomon/base64", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Fast, robust Base64 encoder/decoder for Buffers in C++. Ignores whitespace. Detects corruption and truncation. Ships with extensive tests, a fuzz test and a benchmark.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -116,2 +116,12 @@ # base64 | ||
#### Decoding corrupt or truncated data | ||
Base64 will raise an exception for corrupt or truncated data by default as a defensive measure to prevent data loss and security vulnerabilities. To silence these exceptions and continue decoding in the face of bad data (**not recommended**), use `options.silent`: | ||
```javascript | ||
var Base64 = require('@ronomon/base64'); | ||
var bufferEncoded = Buffer.from('...RWNjbGVzaWFzdGVzIDk6MTEtMTg=', 'ascii'); | ||
var buffer = Base64.decode(bufferEncoded, { silent: true }); | ||
console.log(buffer.toString('utf-8')); | ||
// "Ecclesiastes 9:11-18" | ||
``` | ||
## Tests | ||
@@ -118,0 +128,0 @@ To test the native and Javascript bindings: |
23
test.js
@@ -206,7 +206,7 @@ var Node = { crypto: require('crypto') }; | ||
{ | ||
args: [[], empty], | ||
args: [[], empty, 0], | ||
error: 'source must be a buffer' | ||
}, | ||
{ | ||
args: [empty, []], | ||
args: [empty, [], 0], | ||
error: 'target must be a buffer' | ||
@@ -217,5 +217,22 @@ }, | ||
Buffer.alloc(4), | ||
Buffer.alloc(3 - 1) | ||
Buffer.alloc(3 - 1), | ||
0 | ||
], | ||
error: 'target too small' | ||
}, | ||
{ | ||
args: [empty, empty, '0'], | ||
error: 'flags must be an 8-bit integer' | ||
}, | ||
{ | ||
args: [empty, empty, -1], | ||
error: 'flags must be an 8-bit integer' | ||
}, | ||
{ | ||
args: [empty, empty, 256], | ||
error: 'flags must be an 8-bit integer' | ||
}, | ||
{ | ||
args: [empty, empty, 1.5], | ||
error: 'flags must be an 8-bit integer' | ||
} | ||
@@ -222,0 +239,0 @@ ], |
Sorry, the diff of this file is not supported yet
42593
900
137