New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mailparser

Package Overview
Dependencies
Maintainers
1
Versions
112
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mailparser - npm Package Compare versions

Comparing version 0.4.3 to 0.4.4

686

lib/mailparser.js

@@ -23,4 +23,4 @@ "use strict";

var STATES = {
header: 0x1,
body: 0x2,
header: 0x1,
body: 0x2,
finished: 0x3

@@ -45,3 +45,3 @@ };

*/
function MailParser(options){
function MailParser(options) {

@@ -54,19 +54,24 @@ // Make MailParser a Stream object

* Options object
* @public */ this.options = options || {};
* @public */
this.options = options || {};
/**
* Indicates current state the parser is in
* @private */ this._state = STATES.header;
* @private */
this._state = STATES.header;
/**
* The remaining data from the previos chunk which is waiting to be processed
* @private */ this._remainder = "";
* @private */
this._remainder = "";
/**
* The complete tree structure of the e-mail
* @public */ this.mimeTree = this._createMimeNode();
* @public */
this.mimeTree = this._createMimeNode();
/**
* Current node of the multipart mime tree that is being processed
* @private */ this._currentNode = this.mimeTree;
* @private */
this._currentNode = this.mimeTree;

@@ -78,7 +83,9 @@ // default values for the root node

* An object of already used attachment filenames
* @private */ this._fileNames = {};
* @private */
this._fileNames = {};
/**
* An array of multipart nodes
* @private */ this._multipartTree = [];
* @private */
this._multipartTree = [];

@@ -88,19 +95,24 @@

* This is the final mail structure object that is returned to the client
* @public */ this.mailData = {};
* @public */
this.mailData = {};
/**
* Line counter for debugging
* @private */ this._lineCounter = 0;
* @private */
this._lineCounter = 0;
/**
* Did the last chunk end with \r
* @private */ this._lineFeed = false;
* @private */
this._lineFeed = false;
/**
* Is the "headers" event already emitted
* @private */ this._headersSent = false;
* @private */
this._headersSent = false;
/**
* If the e-mail is in mbox format, unescape ">From " to "From " in body
* @private */ this._isMbox = -1;
* @private */
this._isMbox = -1;
}

@@ -117,7 +129,7 @@ // inherit methods and properties of Stream

*/
MailParser.prototype.write = function(chunk, encoding){
if( this._write(chunk, encoding) ){
if(typeof setImmediate == "function"){
MailParser.prototype.write = function(chunk, encoding) {
if (this._write(chunk, encoding)) {
if (typeof setImmediate == "function") {
setImmediate(this._process.bind(this));
}else{
} else {
process.nextTick(this._process.bind(this));

@@ -137,12 +149,12 @@ }

*/
MailParser.prototype.end = function(chunk, encoding){
MailParser.prototype.end = function(chunk, encoding) {
this._write(chunk, encoding);
if(this.options.debug && this._remainder){
console.log("REMAINDER: "+this._remainder);
if (this.options.debug && this._remainder) {
console.log("REMAINDER: " + this._remainder);
}
if(typeof setImmediate == "function"){
if (typeof setImmediate == "function") {
setImmediate(this._process.bind(this, true));
}else{
} else {
process.nextTick(this._process.bind(this, true));

@@ -159,4 +171,4 @@ }

*/
MailParser.prototype._write = function(chunk, encoding){
if(typeof chunk == "string"){
MailParser.prototype._write = function(chunk, encoding) {
if (typeof chunk == "string") {
chunk = new Buffer(chunk, encoding);

@@ -170,3 +182,3 @@ }

// was already used, skip the \n
if(this._lineFeed && chunk.charAt(0) === "\n"){
if (this._lineFeed && chunk.charAt(0) === "\n") {
chunk = chunk.substr(1);

@@ -176,3 +188,3 @@ }

if(chunk && chunk.length){
if (chunk && chunk.length) {
this._remainder += chunk;

@@ -195,34 +207,33 @@ return true;

*/
MailParser.prototype._process = function(finalPart){
MailParser.prototype._process = function(finalPart) {
finalPart = !!finalPart;
var lines = this._remainder.split(/\r?\n|\r/),
line, i, len;
if(!finalPart){
if (!finalPart) {
this._remainder = lines.pop();
// force line to 1MB chunks if needed
if(this._remainder.length>1048576){
this._remainder = this._remainder.replace(/(.{1048576}(?!\r?\n|\r))/g,"$&\n");
if (this._remainder.length > 1048576) {
this._remainder = this._remainder.replace(/(.{1048576}(?!\r?\n|\r))/g, "$&\n");
}
}
for(i=0, len=lines.length; i < len; i++){
for (i = 0, len = lines.length; i < len; i++) {
line = lines[i];
if(this.options.unescapeSMTP && line.substr(0,2)==".."){
if (this.options.unescapeSMTP && line.substr(0, 2) == "..") {
line = line.substr(1);
}
if(this._isMbox === true && line.match(/^\>+From /)){
if (this._isMbox === true && line.match(/^\>+From /)) {
line = line.substr(1);
}
if(this.options.debug){
console.log("LINE " + (++this._lineCounter) + " ("+this._state+"): "+line);
if (this.options.debug) {
console.log("LINE " + (++this._lineCounter) + " (" + this._state + "): " + line);
}
if(this._state == STATES.header){
if(this._processStateHeader(line) === true){
if (this._state == STATES.header) {
if (this._processStateHeader(line) === true) {
continue;

@@ -232,15 +243,12 @@ }

if(this._state == STATES.body){
if(this._processStateBody(line) === true){
if (this._state == STATES.body) {
if (this._processStateBody(line) === true) {
continue;
}
}
}
if(finalPart){
if(this._state == STATES.header && this._remainder){
if (finalPart) {
if (this._state == STATES.header && this._remainder) {
this._processStateHeader(this._remainder);
if(!this._headersSent){
if (!this._headersSent) {
this.emit("headers", this._currentNode.parsedHeaders);

@@ -250,9 +258,9 @@ this._headersSent = true;

}
if(this._currentNode.content || this._currentNode.stream){
if (this._currentNode.content || this._currentNode.stream) {
this._finalizeContents();
}
this._state = STATES.finished;
if(typeof setImmediate == "function"){
if (typeof setImmediate == "function") {
setImmediate(this._processMimeTree.bind(this));
}else{
} else {
process.nextTick(this._processMimeTree.bind(this));

@@ -274,12 +282,13 @@ }

*/
MailParser.prototype._processStateHeader = function(line){
MailParser.prototype._processStateHeader = function(line) {
var attachment, lastPos = this._currentNode.headers.length - 1,
textContent = false, extension;
textContent = false,
extension;
// Check if the header ends and body starts
if(!line.length){
if(lastPos>=0){
if (!line.length) {
if (lastPos >= 0) {
this._processHeaderLine(lastPos);
}
if(!this._headersSent){
if (!this._headersSent) {
this.emit("headers", this._currentNode.parsedHeaders);

@@ -292,3 +301,3 @@ this._headersSent = true;

// if there's unprocessed header data, do it now
if(lastPos >= 0){
if (lastPos >= 0) {
this._processHeaderLine(lastPos);

@@ -298,3 +307,3 @@ }

// this is a very simple e-mail, no content type set
if(!this._currentNode.parentNode && !this._currentNode.meta.contentType){
if (!this._currentNode.parentNode && !this._currentNode.meta.contentType) {
this._currentNode.meta.contentType = "text/plain";

@@ -306,6 +315,6 @@ }

// detect if this is an attachment or a text node (some agents use inline dispositions for text)
if(textContent && (!this._currentNode.meta.contentDisposition || this._currentNode.meta.contentDisposition == "inline")){
if (textContent && (!this._currentNode.meta.contentDisposition || this._currentNode.meta.contentDisposition == "inline")) {
this._currentNode.attachment = false;
}else if((!textContent || ["attachment", "inline"].indexOf(this._currentNode.meta.contentDisposition)>=0) &&
!this._currentNode.meta.mimeMultipart){
} else if ((!textContent || ["attachment", "inline"].indexOf(this._currentNode.meta.contentDisposition) >= 0) &&
!this._currentNode.meta.mimeMultipart) {
this._currentNode.attachment = true;

@@ -315,3 +324,3 @@ }

// handle attachment start
if(this._currentNode.attachment){
if (this._currentNode.attachment) {

@@ -328,3 +337,3 @@ this._currentNode.checksum = crypto.createHash("md5");

// Update content-type if it's an application/octet-stream and file extension is available
if(this._currentNode.meta.contentType == "application/octet-stream" && mime.lookup(extension)){
if (this._currentNode.meta.contentType == "application/octet-stream" && mime.lookup(extension)) {
this._currentNode.meta.contentType = mime.lookup(extension);

@@ -334,8 +343,10 @@ }

attachment = this._currentNode.meta;
if(this.options.streamAttachments){
if(this._currentNode.meta.transferEncoding == "base64"){
if (this.options.streamAttachments) {
if (this._currentNode.meta.transferEncoding == "base64") {
this._currentNode.stream = new Streams.Base64Stream();
}else if(this._currentNode.meta.transferEncoding == "quoted-printable"){
} else if (this._currentNode.meta.transferEncoding == "quoted-printable") {
this._currentNode.stream = new Streams.QPStream("binary");
}else{
} else if (this._currentNode.meta.transferEncoding == "uuencode") {
this._currentNode.stream = new Streams.UUEStream("binary");
} else {
this._currentNode.stream = new Streams.BinaryStream();

@@ -346,3 +357,3 @@ }

this.emit("attachment", attachment);
}else{
} else {
this._currentNode.content = undefined;

@@ -356,7 +367,7 @@ }

// unfold header lines if needed
if(line.match(/^\s+/) && lastPos>=0){
if (line.match(/^\s+/) && lastPos >= 0) {
this._currentNode.headers[lastPos] += " " + line.trim();
}else{
} else {
this._currentNode.headers.push(line.trim());
if(lastPos>=0){
if (lastPos >= 0) {
// if a complete header line is received, process it

@@ -376,3 +387,3 @@ this._processHeaderLine(lastPos);

*/
MailParser.prototype._processStateBody = function(line){
MailParser.prototype._processStateBody = function(line) {
var i, len, node,

@@ -382,9 +393,9 @@ nodeReady = false;

// Handle multipart boundaries
if(line.substr(0, 2) == "--"){
for(i=0, len = this._multipartTree.length; i<len; i++){
if (line.substr(0, 2) == "--") {
for (i = 0, len = this._multipartTree.length; i < len; i++) {
// check if a new element block starts
if(line == "--" + this._multipartTree[i].boundary){
if (line == "--" + this._multipartTree[i].boundary) {
if(this._currentNode.content || this._currentNode.stream){
if (this._currentNode.content || this._currentNode.stream) {
this._finalizeContents();

@@ -399,13 +410,13 @@ }

break;
}else
} else
// check if a multipart block ends
if(line == "--" + this._multipartTree[i].boundary + "--"){
if (line == "--" + this._multipartTree[i].boundary + "--") {
if(this._currentNode.content || this._currentNode.stream){
if (this._currentNode.content || this._currentNode.stream) {
this._finalizeContents();
}
if(this._multipartTree[i].node.parentNode){
if (this._multipartTree[i].node.parentNode) {
this._currentNode = this._multipartTree[i].node.parentNode;
}else{
} else {
this._currentNode = this._multipartTree[i].node;

@@ -419,3 +430,3 @@ }

}
if(nodeReady){
if (nodeReady) {
return true;

@@ -425,6 +436,6 @@ }

// handle text or attachment line
if(["text/plain", "text/html", "text/calendar"].indexOf(this._currentNode.meta.contentType || "")>=0 &&
!this._currentNode.attachment){
if (["text/plain", "text/html", "text/calendar"].indexOf(this._currentNode.meta.contentType || "") >= 0 &&
!this._currentNode.attachment) {
this._handleTextLine(line);
}else if(this._currentNode.attachment){
} else if (this._currentNode.attachment) {
this._handleAttachmentLine(line);

@@ -448,3 +459,3 @@ }

*/
MailParser.prototype._processHeaderLine = function(pos){
MailParser.prototype._processHeaderLine = function(pos) {
var key, value, parts, line;

@@ -454,8 +465,8 @@

if(!(line = this._currentNode.headers[pos]) || typeof line != "string"){
if (!(line = this._currentNode.headers[pos]) || typeof line != "string") {
return;
}
if(!this._headersSent && this._isMbox < 0){
if((this._isMbox = !!line.match(/^From /))){
if (!this._headersSent && this._isMbox < 0) {
if ((this._isMbox = !!line.match(/^From /))) {
return;

@@ -470,3 +481,3 @@ }

switch(key){
switch (key) {
case "content-type":

@@ -480,3 +491,3 @@ this._parseContentType(value);

this._currentNode.meta.date = new Date(value);
if(Object.prototype.toString.call(this._currentNode.meta.date) != "[object Date]" || this._currentNode.meta.date.toString() == "Invalid Date"){
if (Object.prototype.toString.call(this._currentNode.meta.date) != "[object Date]" || this._currentNode.meta.date.toString() == "Invalid Date") {
this._currentNode.meta.date = datetime.strtotime(value) && new Date(datetime.strtotime(value) * 1000);

@@ -486,5 +497,5 @@ }

case "to":
if(this._currentNode.to && this._currentNode.to.length){
if (this._currentNode.to && this._currentNode.to.length) {
this._currentNode.to = this._currentNode.to.concat(mimelib.parseAddresses(value));
}else{
} else {
this._currentNode.to = mimelib.parseAddresses(value);

@@ -494,5 +505,5 @@ }

case "from":
if(this._currentNode.from && this._currentNode.from.length){
if (this._currentNode.from && this._currentNode.from.length) {
this._currentNode.from = this._currentNode.from.concat(mimelib.parseAddresses(value));
}else{
} else {
this._currentNode.from = mimelib.parseAddresses(value);

@@ -502,5 +513,5 @@ }

case "reply-to":
if(this._currentNode.replyTo && this._currentNode.replyTo.length){
if (this._currentNode.replyTo && this._currentNode.replyTo.length) {
this._currentNode.replyTo = this._currentNode.replyTo.concat(mimelib.parseAddresses(value));
}else{
} else {
this._currentNode.replyTo = mimelib.parseAddresses(value);

@@ -510,5 +521,5 @@ }

case "cc":
if(this._currentNode.cc && this._currentNode.cc.length){
if (this._currentNode.cc && this._currentNode.cc.length) {
this._currentNode.cc = this._currentNode.cc.concat(mimelib.parseAddresses(value));
}else{
} else {
this._currentNode.cc = mimelib.parseAddresses(value);

@@ -518,5 +529,5 @@ }

case "bcc":
if(this._currentNode.bcc && this._currentNode.bcc.length){
if (this._currentNode.bcc && this._currentNode.bcc.length) {
this._currentNode.bcc = this._currentNode.bcc.concat(mimelib.parseAddresses(value));
}else{
} else {
this._currentNode.bcc = mimelib.parseAddresses(value);

@@ -558,12 +569,15 @@ }

if(this._currentNode.parsedHeaders[key]){
if(!Array.isArray(this._currentNode.parsedHeaders[key])){
if (this._currentNode.parsedHeaders[key]) {
if (!Array.isArray(this._currentNode.parsedHeaders[key])) {
this._currentNode.parsedHeaders[key] = [this._currentNode.parsedHeaders[key]];
}
this._currentNode.parsedHeaders[key].push(this._replaceMimeWords(value));
}else{
} else {
this._currentNode.parsedHeaders[key] = this._replaceMimeWords(value);
}
this._currentNode.headers[pos] = {key: key, value: value};
this._currentNode.headers[pos] = {
key: key,
value: value
};
};

@@ -580,7 +594,7 @@

*/
MailParser.prototype._createMimeNode = function(parentNode){
MailParser.prototype._createMimeNode = function(parentNode) {
var node = {
parentNode: parentNode || this._currentNode || null,
headers: [],
parsedHeaders:{},
parsedHeaders: {},
meta: {},

@@ -611,3 +625,3 @@ childNodes: []

*/
MailParser.prototype._parseHeaderLineWithParams = function(value){
MailParser.prototype._parseHeaderLineWithParams = function(value) {
var key, parts, returnValue = {};

@@ -618,3 +632,3 @@

for(var i=0, len = parts.length; i<len; i++){
for (var i = 0, len = parts.length; i < len; i++) {
value = parts[i].split("=");

@@ -641,26 +655,26 @@ key = value.shift().trim().toLowerCase();

*/
MailParser.prototype._parseContentType = function(value){
MailParser.prototype._parseContentType = function(value) {
var fileName;
value = this._parseHeaderLineWithParams(value);
if(value){
if(value.defaultValue){
if (value) {
if (value.defaultValue) {
value.defaultValue = value.defaultValue.toLowerCase();
this._currentNode.meta.contentType = value.defaultValue;
if(value.defaultValue.substr(0,"multipart/".length)=="multipart/"){
if (value.defaultValue.substr(0, "multipart/".length) == "multipart/") {
this._currentNode.meta.mimeMultipart = value.defaultValue.substr("multipart/".length);
}
}else{
} else {
this._currentNode.meta.contentType = "application/octet-stream";
}
if(value.charset){
if (value.charset) {
value.charset = value.charset.toLowerCase();
if(value.charset.substr(0,4)=="win-"){
value.charset = "windows-"+value.charset.substr(4);
}else if(value.charset == "ks_c_5601-1987"){
if (value.charset.substr(0, 4) == "win-") {
value.charset = "windows-" + value.charset.substr(4);
} else if (value.charset == "ks_c_5601-1987") {
value.charset = "cp949";
}else if(value.charset.match(/^utf\d/)){
value.charset = "utf-"+value.charset.substr(3);
}else if(value.charset.match(/^latin[\-_]?\d/)){
value.charset = "iso-8859-"+value.charset.replace(/\D/g,"");
}else if(value.charset.match(/^(us\-)?ascii$/)){
} else if (value.charset.match(/^utf\d/)) {
value.charset = "utf-" + value.charset.substr(3);
} else if (value.charset.match(/^latin[\-_]?\d/)) {
value.charset = "iso-8859-" + value.charset.replace(/\D/g, "");
} else if (value.charset.match(/^(us\-)?ascii$/)) {
value.charset = "utf-8";

@@ -670,13 +684,13 @@ }

}
if(value.format){
if (value.format) {
this._currentNode.meta.textFormat = value.format.toLowerCase();
}
if(value.delsp){
if (value.delsp) {
this._currentNode.meta.textDelSp = value.delsp.toLowerCase();
}
if(value.boundary){
if (value.boundary) {
this._currentNode.meta.mimeBoundary = value.boundary;
}
if(value.method){
if (value.method) {
this._currentNode.meta.method = value.method;

@@ -686,7 +700,7 @@ }

if(!this._currentNode.meta.fileName && (fileName = this._detectFilename(value))){
if (!this._currentNode.meta.fileName && (fileName = this._detectFilename(value))) {
this._currentNode.meta.fileName = fileName;
}
if(value.boundary){
if (value.boundary) {
this._currentNode.meta.mimeBoundary = value.boundary;

@@ -711,10 +725,12 @@ this._multipartTree.push({

*/
MailParser.prototype._detectFilename = function(value){
var fileName="", i=0, parts, encoding, name;
MailParser.prototype._detectFilename = function(value) {
var fileName = "",
i = 0,
parts, encoding, name;
if(value.name){
if (value.name) {
return this._replaceMimeWords(value.name);
}
if(value.filename){
if (value.filename) {
return this._replaceMimeWords(value.filename);

@@ -724,22 +740,22 @@ }

// RFC2231
if(value["name*"]){
if (value["name*"]) {
fileName = value["name*"];
}else if(value["filename*"]){
} else if (value["filename*"]) {
fileName = value["filename*"];
}else if(value["name*0*"]){
while(value["name*"+(i)+"*"]){
fileName += value["name*"+(i++)+"*"];
} else if (value["name*0*"]) {
while (value["name*" + (i) + "*"]) {
fileName += value["name*" + (i++) + "*"];
}
}else if(value["filename*0*"]){
while(value["filename*"+(i)+"*"]){
fileName += value["filename*"+(i++)+"*"];
} else if (value["filename*0*"]) {
while (value["filename*" + (i) + "*"]) {
fileName += value["filename*" + (i++) + "*"];
}
}
if(fileName){
if (fileName) {
parts = fileName.split("'");
encoding = parts.shift();
name = parts.pop();
if(name){
return this._replaceMimeWords(this._replaceMimeWords("=?"+(encoding || "us-ascii")+"?Q?" + name.replace(/%/g,"=")+"?="));
if (name) {
return this._replaceMimeWords(this._replaceMimeWords("=?" + (encoding || "us-ascii") + "?Q?" + name.replace(/%/g, "=") + "?="));
}

@@ -757,3 +773,3 @@ }

*/
MailParser.prototype._parseContentDisposition = function(value){
MailParser.prototype._parseContentDisposition = function(value) {
var fileName;

@@ -763,7 +779,7 @@

if(value){
if(value.defaultValue){
if (value) {
if (value.defaultValue) {
this._currentNode.meta.contentDisposition = value.defaultValue.trim().toLowerCase();
}
if((fileName = this._detectFilename(value))){
if ((fileName = this._detectFilename(value))) {
this._currentNode.meta.fileName = fileName;

@@ -779,9 +795,6 @@ }

*/
MailParser.prototype._parseReferences = function(value){
MailParser.prototype._parseReferences = function(value) {
this._currentNode.references = (this._currentNode.references || []).concat(
(value || "").toString().
trim().
split(/\s+/).
map(this._trimQuotes.bind(this))
);
(value || "").toString().trim().split(/\s+/).map(this._trimQuotes.bind(this))
);
};

@@ -794,9 +807,6 @@

*/
MailParser.prototype._parseInReplyTo = function(value){
MailParser.prototype._parseInReplyTo = function(value) {
this._currentNode.inReplyTo = (this._currentNode.inReplyTo || []).concat(
(value || "").toString().
trim().
split(/\s+/).
map(this._trimQuotes.bind(this))
);
(value || "").toString().trim().split(/\s+/).map(this._trimQuotes.bind(this))
);
};

@@ -810,15 +820,15 @@

*/
MailParser.prototype._parsePriority = function(value){
MailParser.prototype._parsePriority = function(value) {
value = value.toLowerCase().trim();
if(!isNaN(parseInt(value,10))){ // support "X-Priority: 1 (Highest)"
if (!isNaN(parseInt(value, 10))) { // support "X-Priority: 1 (Highest)"
value = parseInt(value, 10) || 0;
if(value == 3){
if (value == 3) {
return "normal";
}else if(value > 3){
} else if (value > 3) {
return "low";
}else{
} else {
return "high";
}
}else{
switch(value){
} else {
switch (value) {
case "non-urgent":

@@ -842,25 +852,25 @@ case "low":

*/
MailParser.prototype._handleTextLine = function(line){
MailParser.prototype._handleTextLine = function(line) {
if(["quoted-printable", "base64"].indexOf(this._currentNode.meta.transferEncoding)>=0 || this._currentNode.meta.textFormat != "flowed"){
if(typeof this._currentNode.content != "string"){
if (["quoted-printable", "base64"].indexOf(this._currentNode.meta.transferEncoding) >= 0 || this._currentNode.meta.textFormat != "flowed") {
if (typeof this._currentNode.content != "string") {
this._currentNode.content = line;
}else{
this._currentNode.content += "\n"+line;
} else {
this._currentNode.content += "\n" + line;
}
}else{
if(typeof this._currentNode.content != "string"){
} else {
if (typeof this._currentNode.content != "string") {
this._currentNode.content = line;
}else if(this._currentNode.content.match(/[ ]$/)){
if(this._currentNode.meta.textFormat == "flowed" && this._currentNode.content.match(/(^|\n)-- $/)){
} else if (this._currentNode.content.match(/[ ]$/)) {
if (this._currentNode.meta.textFormat == "flowed" && this._currentNode.content.match(/(^|\n)-- $/)) {
// handle special case for usenet signatures
this._currentNode.content += "\n"+line;
}else{
if(this._currentNode.meta.textDelSp == "yes"){
this._currentNode.content = this._currentNode.content.replace(/[ ]+$/,"");
this._currentNode.content += "\n" + line;
} else {
if (this._currentNode.meta.textDelSp == "yes") {
this._currentNode.content = this._currentNode.content.replace(/[ ]+$/, "");
}
this._currentNode.content += line;
}
}else{
this._currentNode.content += "\n"+line;
} else {
this._currentNode.content += "\n" + line;
}

@@ -878,17 +888,17 @@ }

*/
MailParser.prototype._handleAttachmentLine = function(line){
if(!this._currentNode.attachment){
MailParser.prototype._handleAttachmentLine = function(line) {
if (!this._currentNode.attachment) {
return;
}
if(this._currentNode.stream){
if(!this._currentNode.streamStarted){
if (this._currentNode.stream) {
if (!this._currentNode.streamStarted) {
this._currentNode.streamStarted = true;
this._currentNode.stream.write(new Buffer(line, "binary"));
}else{
this._currentNode.stream.write(new Buffer("\r\n"+line, "binary"));
} else {
this._currentNode.stream.write(new Buffer("\r\n" + line, "binary"));
}
}else if("content" in this._currentNode){
if(typeof this._currentNode.content!="string"){
} else if ("content" in this._currentNode) {
if (typeof this._currentNode.content != "string") {
this._currentNode.content = line;
}else{
} else {
this._currentNode.content += "\r\n" + line;

@@ -906,31 +916,31 @@ }

*/
MailParser.prototype._finalizeContents = function(){
MailParser.prototype._finalizeContents = function() {
var streamInfo;
if(this._currentNode.content){
if (this._currentNode.content) {
if(!this._currentNode.attachment){
if (!this._currentNode.attachment) {
if(this._currentNode.meta.contentType == "text/html"){
this._currentNode.meta.charset = this._detectHTMLCharset(this._currentNode.content) || this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1";
if (this._currentNode.meta.contentType == "text/html") {
this._currentNode.meta.charset = this._detectHTMLCharset(this._currentNode.content) || this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1";
}
if(this._currentNode.meta.transferEncoding == "quoted-printable"){
if (this._currentNode.meta.transferEncoding == "quoted-printable") {
this._currentNode.content = mimelib.decodeQuotedPrintable(this._currentNode.content, false, this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1");
if(this._currentNode.meta.textFormat == "flowed"){
if(this._currentNode.meta.textDelSp == "yes"){
if (this._currentNode.meta.textFormat == "flowed") {
if (this._currentNode.meta.textDelSp == "yes") {
this._currentNode.content = this._currentNode.content.replace(/(^|\n)-- \n/g, '$1-- \u0000').replace(/ \n/g, '').replace(/(^|\n)-- \u0000/g, '$1-- \n');
}else{
} else {
this._currentNode.content = this._currentNode.content.replace(/(^|\n)-- \n/g, '$1-- \u0000').replace(/ \n/g, ' ').replace(/(^|\n)-- \u0000/g, '$1-- \n');
}
}
}else if(this._currentNode.meta.transferEncoding == "base64"){
} else if (this._currentNode.meta.transferEncoding == "base64") {
this._currentNode.content = mimelib.decodeBase64(this._currentNode.content, this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1");
}else{
} else {
this._currentNode.content = this._convertStringToUTF8(this._currentNode.content);
}
}else{
if(this._currentNode.meta.transferEncoding == "quoted-printable"){
} else {
if (this._currentNode.meta.transferEncoding == "quoted-printable") {
this._currentNode.content = mimelib.decodeQuotedPrintable(this._currentNode.content, false, "binary");
}else if(this._currentNode.meta.transferEncoding == "base64"){
} else if (this._currentNode.meta.transferEncoding == "base64") {

@@ -940,3 +950,6 @@ // WTF? if newlines are not removed, the resulting hash is *always* different

}else{
} else if (this._currentNode.meta.transferEncoding == "uuencode") {
var uuestream = new Streams.UUEStream("binary");
this._currentNode.content = uuestream.decode(new Buffer(this._currentNode.content, "binary"));
} else {
this._currentNode.content = new Buffer(this._currentNode.content, "binary");

@@ -951,8 +964,8 @@ }

if(this._currentNode.stream){
if (this._currentNode.stream) {
streamInfo = this._currentNode.stream.end() || {};
if(streamInfo.checksum){
if (streamInfo.checksum) {
this._currentNode.meta.checksum = streamInfo.checksum;
}
if(streamInfo.length){
if (streamInfo.length) {
this._currentNode.meta.length = streamInfo.length;

@@ -971,18 +984,24 @@ }

*/
MailParser.prototype._processMimeTree = function(){
var returnValue = {}, i, len;
MailParser.prototype._processMimeTree = function() {
var returnValue = {},
i, len;
this.mailData = {html:[], text:[], calendar:[], attachments:[]};
this.mailData = {
html: [],
text: [],
calendar: [],
attachments: []
};
if(!this.mimeTree.meta.mimeMultipart){
if (!this.mimeTree.meta.mimeMultipart) {
this._processMimeNode(this.mimeTree, 0);
}else{
} else {
this._walkMimeTree(this.mimeTree);
}
if(this.mailData.html.length){
for(i=0, len=this.mailData.html.length; i<len; i++){
if(!returnValue.html && this.mailData.html[i].content){
if (this.mailData.html.length) {
for (i = 0, len = this.mailData.html.length; i < len; i++) {
if (!returnValue.html && this.mailData.html[i].content) {
returnValue.html = this.mailData.html[i].content;
}else if(this.mailData.html[i].content){
} else if (this.mailData.html[i].content) {
returnValue.html = this._concatHTML(returnValue.html, this.mailData.html[i].content);

@@ -993,7 +1012,7 @@ }

if(this.mailData.text.length){
for(i=0, len=this.mailData.text.length; i<len; i++){
if(!returnValue.text && this.mailData.text[i].content){
if (this.mailData.text.length) {
for (i = 0, len = this.mailData.text.length; i < len; i++) {
if (!returnValue.text && this.mailData.text[i].content) {
returnValue.text = this.mailData.text[i].content;
}else if(this.mailData.text[i].content){
} else if (this.mailData.text[i].content) {
returnValue.text += this.mailData.text[i].content;

@@ -1005,5 +1024,5 @@ }

if(this.mailData.calendar.length){
if (this.mailData.calendar.length) {
returnValue.alternatives = [];
for(i=0, len=this.mailData.calendar.length; i<len; i++){
for (i = 0, len = this.mailData.calendar.length; i < len; i++) {
returnValue.alternatives.push(this.mailData.calendar[i].content);

@@ -1015,49 +1034,49 @@ }

if(this.mimeTree.subject){
if (this.mimeTree.subject) {
returnValue.subject = this.mimeTree.subject;
}
if(this.mimeTree.references){
if (this.mimeTree.references) {
returnValue.references = this.mimeTree.references;
}
if(this.mimeTree.messageId){
if (this.mimeTree.messageId) {
returnValue.messageId = this.mimeTree.messageId;
}
if(this.mimeTree.inReplyTo){
if (this.mimeTree.inReplyTo) {
returnValue.inReplyTo = this.mimeTree.inReplyTo;
}
if(this.mimeTree.priority){
if (this.mimeTree.priority) {
returnValue.priority = this.mimeTree.priority;
}
if(this.mimeTree.from){
if (this.mimeTree.from) {
returnValue.from = this.mimeTree.from;
}
if(this.mimeTree.replyTo){
if (this.mimeTree.replyTo) {
returnValue.replyTo = this.mimeTree.replyTo;
}
if(this.mimeTree.to){
if (this.mimeTree.to) {
returnValue.to = this.mimeTree.to;
}
if(this.mimeTree.cc){
if (this.mimeTree.cc) {
returnValue.cc = this.mimeTree.cc;
}
if(this.mimeTree.bcc){
if (this.mimeTree.bcc) {
returnValue.bcc = this.mimeTree.bcc;
}
if(this.mimeTree.meta.date){
if (this.mimeTree.meta.date) {
returnValue.date = this.mimeTree.meta.date;
}
if(this.mailData.attachments.length){
if (this.mailData.attachments.length) {
returnValue.attachments = [];
for(i=0, len=this.mailData.attachments.length; i<len; i++){
for (i = 0, len = this.mailData.attachments.length; i < len; i++) {
returnValue.attachments.push(this.mailData.attachments[i].content);

@@ -1067,5 +1086,5 @@ }

if(typeof setImmediate == "function"){
if (typeof setImmediate == "function") {
setImmediate(this.emit.bind(this, "end", returnValue));
}else{
} else {
process.nextTick(this.emit.bind(this, "end", returnValue));

@@ -1081,7 +1100,7 @@ }

*/
MailParser.prototype._walkMimeTree = function(node, level){
MailParser.prototype._walkMimeTree = function(node, level) {
level = level || 1;
for(var i=0, len = node.childNodes.length; i<len; i++){
for (var i = 0, len = node.childNodes.length; i < len; i++) {
this._processMimeNode(node.childNodes[i], level, node.meta.mimeMultipart);
this._walkMimeTree(node.childNodes[i], level+1);
this._walkMimeTree(node.childNodes[i], level + 1);
}

@@ -1099,3 +1118,3 @@ };

*/
MailParser.prototype._processMimeNode = function(node, level, mimeMultipart){
MailParser.prototype._processMimeNode = function(node, level, mimeMultipart) {
var i, len;

@@ -1105,8 +1124,8 @@

if(!node.attachment){
switch(node.meta.contentType){
if (!node.attachment) {
switch (node.meta.contentType) {
case "text/html":
if(mimeMultipart == "mixed" && this.mailData.html.length){
for(i=0, len = this.mailData.html.length; i<len; i++){
if(this.mailData.html[i].level == level){
if (mimeMultipart == "mixed" && this.mailData.html.length) {
for (i = 0, len = this.mailData.html.length; i < len; i++) {
if (this.mailData.html[i].level == level) {
this._joinHTMLNodes(this.mailData.html[i], node.content);

@@ -1117,24 +1136,36 @@ return;

}
this.mailData.html.push({content: this._updateHTMLCharset(node.content || ""), level: level});
this.mailData.html.push({
content: this._updateHTMLCharset(node.content || ""),
level: level
});
return;
case "text/plain":
this.mailData.text.push({content: node.content || "", level: level});
this.mailData.text.push({
content: node.content || "",
level: level
});
return;
case "text/calendar":
if(node.content){
if (node.content) {
node.meta.content = node.content;
}
this.mailData.calendar.push({content: node.meta || {}, level: level});
this.mailData.calendar.push({
content: node.meta || {},
level: level
});
return;
}
}else{
} else {
node.meta = node.meta || {};
if(node.content){
if (node.content) {
node.meta.content = node.content;
}
this.mailData.attachments.push({content: node.meta || {}, level: level});
this.mailData.attachments.push({
content: node.meta || {},
level: level
});
if(this.options.showAttachmentLinks && mimeMultipart == "mixed" && this.mailData.html.length){
for(i=0, len = this.mailData.html.length; i<len; i++){
if(this.mailData.html[i].level == level){
if (this.options.showAttachmentLinks && mimeMultipart == "mixed" && this.mailData.html.length) {
for (i = 0, len = this.mailData.html.length; i < len; i++) {
if (this.mailData.html[i].level == level) {
this._joinHTMLAttachment(this.mailData.html[i], node.meta);

@@ -1154,3 +1185,3 @@ return;

*/
MailParser.prototype._joinHTMLNodes = function(htmlNode, newHTML){
MailParser.prototype._joinHTMLNodes = function(htmlNode, newHTML) {
var inserted = false;

@@ -1166,7 +1197,7 @@

newHTML = newHTML.replace(/<head( [^>]*)?>(.*)<\/head( [^>]*)?>/gi, "").
replace(/<\/?html( [^>]*)?>/gi, "").
trim();
replace(/<\/?html( [^>]*)?>/gi, "").
trim();
// keep only text between <body> tags (if <body exists)
newHTML.replace(/<body(?: [^>]*)?>(.*)<\/body( [^>]*)?>/gi, function(match, body){
newHTML.replace(/<body(?: [^>]*)?>(.*)<\/body( [^>]*)?>/gi, function(match, body) {
newHTML = body.trim();

@@ -1177,3 +1208,3 @@ });

htmlNode.content = htmlNode.content.replace(/<\/body( [^>]*)?>/i, function(match){
htmlNode.content = htmlNode.content.replace(/<\/body( [^>]*)?>/i, function(match) {
inserted = true;

@@ -1183,3 +1214,3 @@ return "<br/>\n" + newHTML + match;

if(!inserted){
if (!inserted) {
htmlNode.content += "<br/>\n" + newHTML;

@@ -1195,3 +1226,3 @@ }

*/
MailParser.prototype._joinHTMLAttachment = function(htmlNode, attachment){
MailParser.prototype._joinHTMLAttachment = function(htmlNode, attachment) {
var inserted = false,

@@ -1205,3 +1236,3 @@ fname = attachment.generatedFileName.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"),

htmlNode.content = htmlNode.content.replace(/<\/body\b[^>]*>/i, function(match){
htmlNode.content = htmlNode.content.replace(/<\/body\b[^>]*>/i, function(match) {
inserted = true;

@@ -1211,3 +1242,3 @@ return "<br/>\n" + newHTML + match;

if(!inserted){
if (!inserted) {
htmlNode.content += "<br/>\n" + newHTML;

@@ -1224,3 +1255,3 @@ }

*/
MailParser.prototype._concatHTML = function(firstNode, secondNode){
MailParser.prototype._concatHTML = function(firstNode, secondNode) {
var headerNode = "",

@@ -1232,17 +1263,17 @@ htmlHeader = "";

if(!secondNode){
if (!secondNode) {
return firstNode;
}
if(!firstNode){
if (!firstNode) {
return secondNode;
}
if(firstNode.substr(0, 1024).replace(/\r?\n/g,"\u0000").match(/^[\s\u0000]*(<\!doctype\b[^>]*?>)?[\s\u0000]*<(html|head)\b[^>]*?>/i)){
if (firstNode.substr(0, 1024).replace(/\r?\n/g, "\u0000").match(/^[\s\u0000]*(<\!doctype\b[^>]*?>)?[\s\u0000]*<(html|head)\b[^>]*?>/i)) {
headerNode = firstNode;
}else if(secondNode.substr(0, 1024).replace(/\r?\n/g,"\u0000").match(/^[\s\u0000]*(<\!doctype\b[^>]*?>)?[\s\u0000]*<(html|head)\b[^>]*?>/i)){
} else if (secondNode.substr(0, 1024).replace(/\r?\n/g, "\u0000").match(/^[\s\u0000]*(<\!doctype\b[^>]*?>)?[\s\u0000]*<(html|head)\b[^>]*?>/i)) {
headerNode = secondNode;
}
if(headerNode){
headerNode.replace(/\r?\n/g, "\u0000").replace(/^[\s\u0000]*(<\!doctype\b[^>]*?>)?[\s\u0000]*<(html|head)\b[^>]*>.*?<\/(head)\b[^>]*>(.*?<body\b[^>]*>)?/i, function(h){
if (headerNode) {
headerNode.replace(/\r?\n/g, "\u0000").replace(/^[\s\u0000]*(<\!doctype\b[^>]*?>)?[\s\u0000]*<(html|head)\b[^>]*>.*?<\/(head)\b[^>]*>(.*?<body\b[^>]*>)?/i, function(h) {
var doctype = h.match(/^[\s\u0000]*(<\!doctype\b[^>]*?>)/i),

@@ -1264,12 +1295,12 @@ html = h.match(/<html\b[^>]*?>/i),

firstNode = firstNode.replace(/\r?\n/g, "\u0000").
replace(/[\s\u0000]*<head\b[^>]*>.*?<\/(head|body)\b[^>]*>/gi, "").
replace(/[\s\u0000]*<[\!\/]?(doctype|html|body)\b[^>]*>[\s\u0000]*/gi, "").
replace(/\u0000/g, "\n");
replace(/[\s\u0000]*<head\b[^>]*>.*?<\/(head|body)\b[^>]*>/gi, "").
replace(/[\s\u0000]*<[\!\/]?(doctype|html|body)\b[^>]*>[\s\u0000]*/gi, "").
replace(/\u0000/g, "\n");
secondNode = secondNode.replace(/\r?\n/g, "\u0000").
replace(/[\s\u0000]*<head\b[^>]*>.*?<\/(head|body)\b[^>]*>/gi, "").
replace(/[\s\u0000]*<[\!\/]?(doctype|html|body)\b[^>]*>[\s\u0000]*/gi, "").
replace(/\u0000/g, "\n");
replace(/[\s\u0000]*<head\b[^>]*>.*?<\/(head|body)\b[^>]*>/gi, "").
replace(/[\s\u0000]*<[\!\/]?(doctype|html|body)\b[^>]*>[\s\u0000]*/gi, "").
replace(/\u0000/g, "\n");
return htmlHeader + firstNode + secondNode + (htmlHeader? (firstNode || secondNode ? "\n" : "") + "</body>\n</html>" : "");
return htmlHeader + firstNode + secondNode + (htmlHeader ? (firstNode || secondNode ? "\n" : "") + "</body>\n</html>" : "");
};

@@ -1285,9 +1316,9 @@

*/
MailParser.prototype._convertString = function(value, fromCharset, toCharset){
MailParser.prototype._convertString = function(value, fromCharset, toCharset) {
toCharset = (toCharset || "utf-8").toUpperCase();
fromCharset = (fromCharset || "utf-8").toUpperCase();
value = typeof value=="string"?new Buffer(value, "binary"):value;
value = typeof value == "string" ? new Buffer(value, "binary") : value;
if(toCharset == fromCharset){
if (toCharset == fromCharset) {
return value;

@@ -1307,3 +1338,3 @@ }

*/
MailParser.prototype._convertStringToUTF8 = function(value){
MailParser.prototype._convertStringToUTF8 = function(value) {
value = this._convertString(value, this._currentNode.meta.charset || this.options.defaultCharset || "iso-8859-1").toString("utf-8");

@@ -1319,3 +1350,3 @@ return value;

*/
MailParser.prototype._encodeString = function(value){
MailParser.prototype._encodeString = function(value) {
value = this._replaceMimeWords(this._convertStringToUTF8(value));

@@ -1331,8 +1362,8 @@ return value;

*/
MailParser.prototype._replaceMimeWords = function(value){
MailParser.prototype._replaceMimeWords = function(value) {
return value.
replace(/(=\?[^?]+\?[QqBb]\?[^?]+\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]+\?=)/g, "$1"). // join mimeWords
replace(/\=\?[^?]+\?[QqBb]\?[^?]+\?=/g, (function(a){
return mimelib.decodeMimeWord(a.replace(/\s/g,''));
}).bind(this));
replace(/(=\?[^?]+\?[QqBb]\?[^?]+\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]+\?=)/g, "$1"). // join mimeWords
replace(/\=\?[^?]+\?[QqBb]\?[^?]+\?=/g, (function(a) {
return mimelib.decodeMimeWord(a.replace(/\s/g, ''));
}).bind(this));
};

@@ -1346,8 +1377,8 @@

*/
MailParser.prototype._trimQuotes = function(value){
MailParser.prototype._trimQuotes = function(value) {
value = (value || "").trim();
if((value.charAt(0)=='"' && value.charAt(value.length-1)=='"') ||
(value.charAt(0)=="'" && value.charAt(value.length-1)=="'") ||
(value.charAt(0)=="<" && value.charAt(value.length-1)==">")){
value = value.substr(1,value.length-2);
if ((value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') ||
(value.charAt(0) == "'" && value.charAt(value.length - 1) == "'") ||
(value.charAt(0) == "<" && value.charAt(value.length - 1) == ">")) {
value = value.substr(1, value.length - 2);
}

@@ -1372,25 +1403,26 @@ return value;

*/
MailParser.prototype._generateFileName = function(fileName, contentType){
var ext, defaultExt = "", fileRootName;
MailParser.prototype._generateFileName = function(fileName, contentType) {
var ext, defaultExt = "",
fileRootName;
if(contentType){
if (contentType) {
defaultExt = mime.extension(contentType);
defaultExt = defaultExt?"."+defaultExt:"";
defaultExt = defaultExt ? "." + defaultExt : "";
}
fileName = fileName || "attachment"+defaultExt;
fileName = fileName || "attachment" + defaultExt;
// remove path if it is included in the filename
fileName = fileName.toString().split(/[\/\\]+/).pop().replace(/^\.+/,"") || "attachment";
fileName = fileName.toString().split(/[\/\\]+/).pop().replace(/^\.+/, "") || "attachment";
fileRootName = fileName.replace(/(?:\-\d+)+(\.[^.]*)$/, "$1") || "attachment";
if(fileRootName in this._fileNames){
if (fileRootName in this._fileNames) {
this._fileNames[fileRootName]++;
ext = fileName.substr((fileName.lastIndexOf(".") || 0)+1);
if(ext == fileName){
fileName += "-" + this._fileNames[fileRootName];
}else{
ext = fileName.substr((fileName.lastIndexOf(".") || 0) + 1);
if (ext == fileName) {
fileName += "-" + this._fileNames[fileRootName];
} else {
fileName = fileName.substr(0, fileName.length - ext.length - 1) + "-" + this._fileNames[fileRootName] + "." + ext;
}
}else{
} else {
this._fileNames[fileRootName] = 0;

@@ -1409,15 +1441,15 @@ }

*/
MailParser.prototype._updateHTMLCharset = function(html){
MailParser.prototype._updateHTMLCharset = function(html) {
html = html.replace(/\n/g,"\u0000").
replace(/<meta[^>]*>/gi, function(meta){
if(meta.match(/http\-equiv\s*=\s*"?content\-type/i)){
return '<meta http-equiv="content-type" content="text/html; charset=utf-8" />';
}
if(meta.match(/\scharset\s*=\s*['"]?[\w\-]+["'\s>\/]/i)){
return '<meta charset="utf-8"/>';
}
return meta;
}).
replace(/\u0000/g,"\n");
html = html.replace(/\n/g, "\u0000").
replace(/<meta[^>]*>/gi, function(meta) {
if (meta.match(/http\-equiv\s*=\s*"?content\-type/i)) {
return '<meta http-equiv="content-type" content="text/html; charset=utf-8" />';
}
if (meta.match(/\scharset\s*=\s*['"]?[\w\-]+["'\s>\/]/i)) {
return '<meta charset="utf-8"/>';
}
return meta;
}).
replace(/\u0000/g, "\n");

@@ -1433,16 +1465,16 @@ return html;

*/
MailParser.prototype._detectHTMLCharset = function(html){
MailParser.prototype._detectHTMLCharset = function(html) {
var charset, input, meta;
if(typeof html !=" string"){
if (typeof html != " string") {
html = html.toString("ascii");
}
if((meta = html.match(/<meta\s+http-equiv=["']content-type["'][^>]*?>/i))){
if ((meta = html.match(/<meta\s+http-equiv=["']content-type["'][^>]*?>/i))) {
input = meta[0];
}
if(input){
if (input) {
charset = input.match(/charset\s?=\s?([a-zA-Z\-_:0-9]*);?/);
if(charset){
if (charset) {
charset = (charset[1] || "").trim().toLowerCase();

@@ -1452,3 +1484,3 @@ }

if(!charset && (meta = html.match(/<meta\s+charset=["']([^'"<\/]*?)["']/i))){
if (!charset && (meta = html.match(/<meta\s+charset=["']([^'"<\/]*?)["']/i))) {
charset = (meta[1] || "").trim().toLowerCase();

@@ -1458,2 +1490,2 @@ }

return charset;
};
};

@@ -7,3 +7,4 @@ "use strict";

encodinglib = require("encoding"),
crypto = require("crypto");
crypto = require("crypto"),
uue = require('uue');

@@ -13,2 +14,3 @@ module.exports.Base64Stream = Base64Stream;

module.exports.BinaryStream = BinaryStream;
module.exports.UUEStream = UUEStream;

@@ -149,2 +151,65 @@ function Base64Stream(){

};
};
// this is not a stream, it buffers data and decodes after end
function UUEStream(charset){
Stream.call(this);
this.writable = true;
this.checksum = crypto.createHash("md5");
this.length = 0;
this.buf = [];
this.buflen = 0;
this.charset = charset || "UTF-8";
this.current = undefined;
}
utillib.inherits(UUEStream, Stream);
UUEStream.prototype.write = function(data){
this.buf.push(data);
this.buflen += data.length;
return true;
};
UUEStream.prototype.end = function(data){
if(data){
this.write(data);
}
this.flush();
this.emit("end");
return {
length: this.length,
checksum: this.checksum.digest("hex")
};
};
UUEStream.prototype.flush = function(){
var buffer = this.decode(Buffer.concat(this.buf, this.buflen));
this.length += buffer.length;
this.checksum.update(buffer);
this.emit("data", buffer);
};
UUEStream.prototype.decode = function(buffer){
var filename;
filename = buffer.slice(0, Math.min(buffer.length, 1024)).toString().split(/\s/)[2] || '';
if(!filename){
return new Buffer(0);
}
buffer = uue.decodeFile(buffer.toString('ascii').replace(/\r\n/g, '\n'), filename);
if(this.charset.toLowerCase() == "binary"){
// do nothing
}else if(this.charset.toLowerCase() != "utf-8"){
buffer = encodinglib.convert(buffer, "utf-8", this.charset);
}
return buffer;
};
{
"name": "mailparser",
"description": "Asynchronous and non-blocking parser for mime encoded e-mail messages",
"version": "0.4.3",
"author" : "Andris Reinman",
"maintainers":[
{
"name":"andris",
"email":"andris@node.ee"
}
],
"repository" : {
"type" : "git",
"url" : "http://github.com/andris9/mailparser.git"
},
"scripts":{
"test": "nodeunit test/"
},
"main" : "./lib/mailparser",
"licenses" : [
{
"type": "MIT",
"url": "http://github.com/andris9/mailparser/blob/master/LICENSE"
}
],
"dependencies": {
"mimelib": ">=0.2.6",
"encoding": ">=0.1.4",
"mime": "*"
},
"devDependencies": {
"nodeunit": "*"
},
"engine": {
"node": ">=0.4"
},
"keywords": ["e-mail", "mime", "parser"]
"name": "mailparser",
"description": "Asynchronous and non-blocking parser for mime encoded e-mail messages",
"version": "0.4.4",
"author": "Andris Reinman",
"maintainers": [
{
"name": "andris",
"email": "andris@node.ee"
}
],
"repository": {
"type": "git",
"url": "http://github.com/andris9/mailparser.git"
},
"scripts": {
"test": "nodeunit test/"
},
"main": "./lib/mailparser",
"licenses": [
{
"type": "MIT",
"url": "http://github.com/andris9/mailparser/blob/master/LICENSE"
}
],
"dependencies": {
"mimelib": ">=0.2.6",
"encoding": ">=0.1.4",
"mime": "*",
"uue": "~1.0.0"
},
"devDependencies": {
"nodeunit": "*"
},
"engine": {
"node": ">=0.4"
},
"keywords": [
"e-mail",
"mime",
"parser"
]
}

@@ -424,2 +424,19 @@ var MailParser = require("../lib/mailparser").MailParser,

});
},
"UUENCODE": function(test){
var encodedText = "Content-Type: application/octet-stream\r\n"+
"Content-Transfer-Encoding: uuencode\r\n"+
"\r\n"+
"begin 644 buffer.bin\r\n"+
"#0V%T\r\n"+
"`\r\n"+
"end",
mail = new Buffer(encodedText, "utf-8");
var mailparser = new MailParser();
mailparser.end(mail);
mailparser.on("end", function(mail){
test.equal(mail.attachments[0].content.toString(), "Cat");
test.done();
});
}

@@ -1203,2 +1220,37 @@

},
"Stream integrity - uuencode": function(test){
var encodedText = "Content-type: multipart/mixed; boundary=ABC\r\n"+
"\r\n"+
"--ABC\r\n"+
"Content-Type: application/octet-stream\r\n"+
"Content-Transfer-Encoding: uuencode\r\n"+
"\r\n"+
"begin 644 buffer.bin\r\n"+
"#0V%T\r\n"+
"`\r\n"+
"end\r\n"+
"--ABC--",
expectedHash = "fa3ebd6742c360b2d9652b7f78d9bd7d",
mail = new Buffer(encodedText, "utf-8");
var mailparser = new MailParser({streamAttachments: true});
for(var i=0, len = mail.length; i<len; i++){
mailparser.write(new Buffer([mail[i]]));
}
test.expect(3);
mailparser.on("attachment", function(attachment){
test.ok(attachment.stream, "Stream detected");
});
mailparser.end();
mailparser.on("end", function(mail){
test.equal(mail.attachments && mail.attachments[0] && mail.attachments[0].checksum, expectedHash);
test.equal(mail.attachments && mail.attachments[0] && mail.attachments[0].length, 3);
test.done();
});
},
"Stream multiple attachments": function(test){

@@ -1205,0 +1257,0 @@ var encodedText = "Content-type: multipart/mixed; boundary=ABC\r\n"+

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