Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dicer

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dicer - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

test/fixtures/nested-full/original

158

lib/Dicer.js

@@ -12,75 +12,32 @@ var EventEmitter = require('events').EventEmitter,

function Dicer(conf) {
function Dicer(opts) {
if (!(this instanceof Dicer))
return new Dicer(conf);
return new Dicer(opts);
EventEmitter.call(this);
if (typeof conf.boundary !== 'string')
if (!opts.headerFirst && typeof opts.boundary !== 'string')
throw new TypeError('Boundary required');
var self = this, isPreamble = true, inHeader = true, dashes = 0;
if (typeof opts.boundary === 'string')
this.setBoundary(opts.boundary);
else
this._bparser = undefined;
this._headerFirst = opts.headerFirst;
var self = this;
this._dashes = 0;
this._isPreamble = true;
this._justMatched = false;
this._firstWrite = true;
this._bparser = new StreamSearch('\r\n--' + conf.boundary);
this._bparser.on('info', function redo(isMatch, data, start, end) {
var buf;
if (!self._part && self._justMatched && data) {
var i = 0;
while (dashes < 2 && (start + i) < end) {
if (data[start + i] === 45) {
++i;
++dashes;
} else {
if (dashes)
buf = B_ONEDASH;
dashes = 0;
break;
}
}
if (dashes === 2) {
if ((start + i) < end && self._events['trailer'])
self.emit('trailer', data.slice(start + i, end));
self.emit('end');
self.destroy();
}
if (dashes)
return;
}
if (self._justMatched)
self._justMatched = false;
if (!self._part) {
self._part = new PartStream();
self.emit(isPreamble ? 'preamble' : 'part', self._part);
if (!isPreamble)
inHeader = true;
}
if (data && start < end) {
if (isPreamble || !inHeader) {
if (buf)
self._part.emit('data', buf);
self._part.emit('data', data.slice(start, end));
} else if (!isPreamble && inHeader) {
if (buf)
self._hparser.push(buf);
var r = self._hparser.push(data.slice(start, end));
if (!inHeader && r !== undefined && r < end)
redo(false, data, start + r, end);
}
}
if (isMatch) {
if (isPreamble)
isPreamble = false;
self._hparser.reset();
self._part.emit('end');
self._part = undefined;
self._justMatched = true;
dashes = 0;
}
});
this._inHeader = true;
this._part = undefined;
this._hparser = new HeaderParser();
this._hparser.on('header', function(header) {
inHeader = false;
self._inHeader = false;
self._part.emit('header', header);
});
this.writable = true;

@@ -96,2 +53,14 @@ }

if (this._headerFirst && this._isPreamble) {
if (!this._part) {
this._part = new PartStream();
this.emit('preamble', this._part);
}
var r = this._hparser.push(data);
if (!this._inHeader && r !== undefined && r < data.length)
data = data.slice(r);
else
return true;
}
// allows for "easier" testing

@@ -119,7 +88,70 @@ if (this._firstWrite) {

this._hparser = undefined;
this._justMatched = false;
this._firstWrite = true;
this.emit('close');
};
Dicer.prototype.setBoundary = function(boundary) {
var self = this;
this._bparser = new StreamSearch('\r\n--' + boundary);
this._bparser.on('info', function(isMatch, data, start, end) {
self._oninfo(isMatch, data, start, end);
});
};
Dicer.prototype._oninfo = function(isMatch, data, start, end) {
var buf;
if (!this._part && this._justMatched && data) {
var i = 0;
while (this._dashes < 2 && (start + i) < end) {
if (data[start + i] === 45) {
++i;
++this._dashes;
} else {
if (this._dashes)
buf = B_ONEDASH;
this._dashes = 0;
break;
}
}
if (this._dashes === 2) {
if ((start + i) < end && this._events.trailer)
this.emit('trailer', data.slice(start + i, end));
this.emit('end');
this.destroy();
}
if (this._dashes)
return;
}
if (this._justMatched)
this._justMatched = false;
if (!this._part) {
this._part = new PartStream();
this.emit(this._isPreamble ? 'preamble' : 'part', this._part);
if (!this._isPreamble)
this._inHeader = true;
}
if (data && start < end) {
if (this._isPreamble || !this._inHeader) {
if (buf)
this._part.emit('data', buf);
this._part.emit('data', data.slice(start, end));
} else if (!this._isPreamble && this._inHeader) {
if (buf)
this._hparser.push(buf);
var r = this._hparser.push(data.slice(start, end));
if (!this._inHeader && r !== undefined && r < end)
this._oninfo(false, data, start + r, end);
}
}
if (isMatch) {
if (this._isPreamble)
this._isPreamble = false;
this._hparser.reset();
this._part.emit('end');
this._part = undefined;
this._justMatched = true;
this._dashes = 0;
}
};
module.exports = Dicer;
{ "name": "dicer",
"version": "0.0.4",
"version": "0.0.5",
"author": "Brian White <mscdex@mscdex.net>",

@@ -4,0 +4,0 @@ "description": "A very fast streaming multipart parser for node.js",

@@ -35,3 +35,2 @@

var m;
console.dir(req.headers['content-type']);
if (req.method === 'POST'

@@ -83,5 +82,5 @@ && req.headers['content-type']

* **preamble**(< _ReadableStream_ >stream) - Emitted for preamble data if you should happen to need it (this should almost always be ignored though).
* **preamble**(< _PartStream_ >stream) - Emitted for preamble if you should happen to need it (can usually be ignored).
* **trailer**(< _Buffer_ >data) - Emitted when trailing data was found after the terminating boundary (as with the preamble, this should be ignored too).
* **trailer**(< _Buffer_ >data) - Emitted when trailing data was found after the terminating boundary (as with the preamble, this can usually be ignored too).

@@ -96,6 +95,8 @@

* **reset**() - _(void)_ - Resets internal state.
* **headerFirst** - _boolean_ - If true, preamble header parsing will be performed first.
* **setBoundary**(< _string_ >boundary) - _(void)_ - Sets the boundary to use for parsing and performs some initialization needed for parsing. You should only need to use this if you set `headerFirst` to true in the constructor and are parsing the boundary from the preamble header.
_PartStream_ is a _ReadableStream_

@@ -106,2 +107,2 @@

* **header**(< _object_ >header) - An object containing the header for this particular part. Each property value is an _array_ of one or more header values.
* **header**(< _object_ >header) - An object containing the header for this particular part. Each property value is an _array_ of one or more string values.

@@ -33,3 +33,3 @@ var assert = require('assert'),

parser.on('header', function(header) {
assert(!fired, errPrefix + 'Header event fired more than once')
assert(!fired, errPrefix + 'Header event fired more than once');
fired = true;

@@ -36,0 +36,0 @@ assert.deepEqual(header, v.expected, errPrefix + 'Parsed result mismatch');

var Dicer = require('..');
var assert = require('assert'),
fs = require('fs');
fs = require('fs'),
inspect = require('util').inspect;

@@ -9,3 +10,3 @@ var FIXTURES_ROOT = __dirname + '/fixtures/';

{ source: 'nested',
boundary: 'AaB03x',
opts: { boundary: 'AaB03x' },
chsize: 32,

@@ -16,3 +17,3 @@ nparts: 2,

{ source: 'many',
boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR',
opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
chsize: 16,

@@ -22,10 +23,40 @@ nparts: 7,

},
{ source: 'nested-full',
opts: { boundary: 'AaB03x', headerFirst: true },
chsize: 32,
nparts: 2,
what: 'One nested multipart with preceding header'
},
].forEach(function(v) {
var fd = fs.openSync(FIXTURES_ROOT + v.source + '/original', 'r'), n = 0,
var fd, n = 0, buffer = new Buffer(v.chsize),
errPrefix = '[' + v.what + ']: ',
buffer = new Buffer(v.chsize),
state = { done: false, parts: [] },
state = { done: false, parts: [], preamble: undefined },
part = { body: undefined, bodylen: 0, header: undefined };
var dicer = new Dicer({ boundary: v.boundary });
fd = fs.openSync(FIXTURES_ROOT + v.source + '/original', 'r')
var dicer = new Dicer(v.opts);
dicer.on('preamble', function(p) {
var preamble = { body: undefined, bodylen: 0, header: undefined };
p.on('header', function(h) {
preamble.header = h;
});
p.on('data', function(data) {
// make a copy because we are using readSync which re-uses a buffer ...
var copy = new Buffer(data.length);
data.copy(copy);
data = copy;
if (!preamble.body)
preamble.body = [ data ];
else
preamble.body.push(data);
preamble.bodylen += data.length;
});
p.on('end', function() {
if (part.body)
part.body = Buffer.concat(part.body, part.bodylen);
if (part.body || preamble.header)
state.preamble = preamble;
});
});
dicer.on('part', function(p) {

@@ -68,5 +99,35 @@ p.on('header', function(h) {

assert(state.done, errPrefix + 'Parser did not finish');
var preamble = undefined;
if (fs.existsSync(FIXTURES_ROOT + v.source + '/preamble')) {
var prebody = fs.readFileSync(FIXTURES_ROOT + v.source + '/preamble');
if (prebody.length) {
preamble = {
body: prebody,
bodylen: prebody.length,
header: undefined
};
}
}
if (fs.existsSync(FIXTURES_ROOT + v.source + '/preamble.header')) {
var prehead = JSON.parse(fs.readFileSync(FIXTURES_ROOT + v.source
+ '/preamble.header', 'binary'));
if (!preamble) {
preamble = {
body: undefined,
bodylen: 0,
header: prehead
};
}
}
assert.deepEqual(state.preamble, preamble, errPrefix
+ 'Preamble mismatch:\nActual:' + inspect(state.preamble)
+ '\nExpected: ' + inspect(preamble));
assert.equal(state.parts.length, v.nparts,
errPrefix + 'Part count mismatch. Actual: ' + state.parts.length
+ '. Expected: ' + v.nparts);
errPrefix + 'Part count mismatch:\nActual: ' + state.parts.length
+ '\nExpected: ' + v.nparts);
for (var i = 0, header, body; i < v.nparts; ++i) {

@@ -79,10 +140,13 @@ body = fs.readFileSync(FIXTURES_ROOT + v.source + '/part' + (i+1));

header = undefined;
try {
if (fs.existsSync(FIXTURES_ROOT + v.source + '/part' + (i+1) + '.header')) {
header = fs.readFileSync(FIXTURES_ROOT + v.source
+ '/part' + (i+1) + '.header', 'binary');
header = JSON.parse(header);
} catch (err) {}
}
assert.deepEqual(state.parts[i].header, header,
errPrefix + 'Part #' + (i+1) + ' parsed header mismatch');
errPrefix + 'Part #' + (i+1)
+ ' parsed header mismatch:\nActual: '
+ inspect(state.parts[i].header)
+ '\nExpected: ' + inspect(header));
}
});

@@ -1,2 +0,4 @@

require('./test-headerparser');
require('./test-multipart');
require('fs').readdirSync(__dirname).forEach(function(f) {
if (f.substr(0, 5) === 'test-')
require('./' + f);
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc