Absurd input source global variable in Binc imap caused the indexer to crash when an email message contained attachments which were disguised messages (ie: x-mimehtml), because this would cause a recursive call into Binc with a different data source (ie: string instead of original fd, clobbering the original source

This commit is contained in:
Jean-Francois Dockes
2012-05-24 14:52:41 +02:00
parent 9c746749df
commit 61a2e28a7c
16 changed files with 171 additions and 672 deletions
+4 -4
View File
@@ -8,12 +8,12 @@ PROGS = trbinc
all: depend $(LIBS)
SRCS = mime-getpart.cc mime-parsefull.cc mime-parseonlyheader.cc \
mime-printbody.cc mime-printdoc.cc mime-printheader.cc mime.cc \
SRCS = mime-parsefull.cc mime-parseonlyheader.cc \
mime-printbody.cc mime.cc \
convert.cc iodevice.cc iofactory.cc
OBJS = mime-getpart.o mime-parsefull.o mime-parseonlyheader.o \
mime-printbody.o mime-printdoc.o mime-printheader.o mime.o \
OBJS = mime-parsefull.o mime-parseonlyheader.o \
mime-printbody.o mime.o \
convert.o iodevice.o iofactory.o
libmime.a : $(OBJS)
-90
View File
@@ -1,90 +0,0 @@
/* -*- mode:c++;c-basic-offset:2 -*- */
/* --------------------------------------------------------------------
* Filename:
* address.cc
*
* Description:
* Implementation of the Address class.
* --------------------------------------------------------------------
* Copyright 2002-2005 Andreas Aardal Hanssen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
* --------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "address.h"
#include "convert.h"
#include <string>
#ifndef NO_NAMESPACES
using namespace ::std;
using namespace Binc;
#endif /* NO_NAMESPACES */
//------------------------------------------------------------------------
Address::Address(const string &name, const string &addr)
{
string::size_type pos = addr.find('@');
this->name = name;
if (pos != string::npos) {
this->local = addr.substr(0, pos);
this->host = addr.substr(pos + 1);
} else this->local = addr;
}
//------------------------------------------------------------------------
Address::Address(const string &wholeaddress)
{
string::size_type start = wholeaddress.find('<');
string addr;
if (start != string::npos)
addr = wholeaddress.substr(start + 1);
else
addr = wholeaddress;
trim(addr, "<>");
if (start != string::npos)
name = wholeaddress.substr(0, start);
else
name = string();
trim(name);
trim(name, "\"");
start = addr.find('@');
local = addr.substr(0, start);
host = addr.substr(start + 1);
trim(local);
trim(host);
trim(name);
}
//------------------------------------------------------------------------
string Address::toParenList(void) const
{
string tmp = "(";
tmp += name.empty() ? "NIL" : toImapString(name);
tmp += " NIL ";
tmp += local.empty() ? "\"\"" : toImapString(local);
tmp += " ";
tmp += host.empty() ? "\"\"" : toImapString(host);
tmp += ")";
return tmp;
}
-52
View File
@@ -1,52 +0,0 @@
/* -*- mode:c++;c-basic-offset:2 -*- */
/* --------------------------------------------------------------------
* Filename:
* src/mailbox/address.h
*
* Description:
* Declaration of the Address class.
* --------------------------------------------------------------------
* Copyright 2002-2005 Andreas Aardal Hanssen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
* --------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef address_h_included
#define address_h_included
#include <string>
namespace Binc {
//------------------------------------------------------------------------
class Address {
public:
std::string name;
std::string local;
std::string host;
//--
std::string toParenList(void) const;
//--
Address(const std::string &name, const std::string &addr);
Address(const std::string &wholeaddr);
};
}
#endif
-3
View File
@@ -39,9 +39,6 @@
#include <cstdlib>
#include <cstring>
#include "address.h"
//#include "depot.h"
namespace Binc {
//----------------------------------------------------------------------
-96
View File
@@ -1,96 +0,0 @@
/* -*- mode:c++;c-basic-offset:2 -*- */
/* --------------------------------------------------------------------
* Filename:
* mime-getpart.cc
*
* Description:
* Implementation of main mime parser components
* --------------------------------------------------------------------
* Copyright 2002-2005 Andreas Aardal Hanssen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
* --------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "mime.h"
#include "convert.h"
#include <string>
#include <vector>
#include <map>
#include <exception>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#ifndef NO_NAMESPACES
using namespace ::std;
#endif /* NO_NAMESPACES */
//------------------------------------------------------------------------
const Binc::MimePart *Binc::MimePart::getPart(const string &findpart,
string genpart, FetchType fetchType) const
{
if (findpart == genpart)
return this;
if (isMultipart()) {
if (members.size() != 0) {
vector<MimePart>::const_iterator i = members.begin();
int part = 1;
while (i != members.end()) {
BincStream ss;
ss << genpart;
if (genpart != "")
ss << ".";
ss << part;
const MimePart *m;
if ((m = (*i).getPart(findpart, ss.str())) != 0) {
if (fetchType == FetchHeader && m->isMessageRFC822())
m = &m->members[0];
return m;
}
++i;
++part;
}
}
} else if (isMessageRFC822()) {
if (members.size() == 1) {
const MimePart *m = members[0].getPart(findpart, genpart);
return m;
} else {
return 0;
}
} else {
// Singlepart
if (genpart != "")
genpart += ".";
genpart += "1";
if (findpart == genpart)
return this;
}
return 0;
}
+1 -1
View File
@@ -39,6 +39,7 @@ namespace Binc {
class MimeInputSource {
public:
// Note that we do NOT take ownership of fd, won't close it on delete
inline MimeInputSource(int fd, unsigned int start = 0);
virtual inline ~MimeInputSource(void);
@@ -211,6 +212,5 @@ namespace Binc {
}
}
extern Binc::MimeInputSource *mimeSource;
#endif
+55 -57
View File
@@ -27,28 +27,27 @@
#include <config.h>
#endif
#include "mime.h"
#include "mime-utils.h"
#include "mime-inputsource.h"
#include "convert.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <string>
#include <vector>
#include <map>
#include <exception>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
Binc::MimeInputSource *mimeSource = 0;
#ifndef NO_NAMESPACES
using namespace ::std;
#endif /* NO_NAMESPACES */
#undef MPF
#include "mime.h"
#include "mime-utils.h"
#include "mime-inputsource.h"
#include "convert.h"
// #define MPF
#ifdef MPF
#define MPFDEB(X) fprintf X
#else
@@ -56,19 +55,15 @@ using namespace ::std;
#endif
//------------------------------------------------------------------------
void Binc::MimeDocument::parseFull(int fd) const
void Binc::MimeDocument::parseFull(int fd)
{
if (allIsParsed)
return;
allIsParsed = true;
if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
delete mimeSource;
mimeSource = new MimeInputSource(fd);
} else {
mimeSource->reset();
}
delete doc_mimeSource;
doc_mimeSource = new MimeInputSource(fd);
headerstartoffsetcrlf = 0;
headerlength = 0;
@@ -80,24 +75,24 @@ void Binc::MimeDocument::parseFull(int fd) const
int bsize = 0;
string bound;
doParseFull(bound, bsize);
doParseFull(doc_mimeSource, bound, bsize);
// eat any trailing junk to get the correct size
char c;
while (mimeSource->getChar(&c));
while (doc_mimeSource->getChar(&c));
size = mimeSource->getOffset();
size = doc_mimeSource->getOffset();
}
void Binc::MimeDocument::parseFull(istream& s) const
void Binc::MimeDocument::parseFull(istream& s)
{
if (allIsParsed)
return;
allIsParsed = true;
delete mimeSource;
mimeSource = new MimeInputSourceStream(s);
delete doc_mimeSource;
doc_mimeSource = new MimeInputSourceStream(s);
headerstartoffsetcrlf = 0;
headerlength = 0;
@@ -109,17 +104,18 @@ void Binc::MimeDocument::parseFull(istream& s) const
int bsize = 0;
string bound;
doParseFull(bound, bsize);
doParseFull(doc_mimeSource, bound, bsize);
// eat any trailing junk to get the correct size
char c;
while (mimeSource->getChar(&c));
while (doc_mimeSource->getChar(&c));
size = mimeSource->getOffset();
size = doc_mimeSource->getOffset();
}
//------------------------------------------------------------------------
static bool parseOneHeaderLine(Binc::Header *header, unsigned int *nlines)
bool Binc::MimePart::parseOneHeaderLine(Binc::Header *header,
unsigned int *nlines)
{
using namespace ::Binc;
char c;
@@ -202,16 +198,16 @@ static bool parseOneHeaderLine(Binc::Header *header, unsigned int *nlines)
}
//------------------------------------------------------------------------
static void parseHeader(Binc::Header *header, unsigned int *nlines)
void Binc::MimePart::parseHeader(Binc::Header *header, unsigned int *nlines)
{
while (parseOneHeaderLine(header, nlines))
{ }
}
//------------------------------------------------------------------------
static void analyzeHeader(Binc::Header *header, bool *multipart,
bool *messagerfc822, string *subtype,
string *boundary)
void Binc::MimePart::analyzeHeader(Binc::Header *header, bool *multipart,
bool *messagerfc822, string *subtype,
string *boundary)
{
using namespace ::Binc;
@@ -267,11 +263,11 @@ static void analyzeHeader(Binc::Header *header, bool *multipart,
}
}
static void parseMessageRFC822(vector<Binc::MimePart> *members,
bool *foundendofpart,
unsigned int *bodylength,
unsigned int *nbodylines,
const string &toboundary)
void Binc::MimePart::parseMessageRFC822(vector<Binc::MimePart> *members,
bool *foundendofpart,
unsigned int *bodylength,
unsigned int *nbodylines,
const string &toboundary)
{
using namespace ::Binc;
@@ -286,7 +282,7 @@ static void parseMessageRFC822(vector<Binc::MimePart> *members,
// parsefull returns the number of bytes that need to be removed
// from the body because of the terminating boundary string.
int bsize = 0;
if (m.doParseFull(toboundary, bsize))
if (m.doParseFull(mimeSource, toboundary, bsize))
*foundendofpart = true;
// make sure bodylength doesn't overflow
@@ -307,8 +303,8 @@ static void parseMessageRFC822(vector<Binc::MimePart> *members,
members->push_back(m);
}
static bool skipUntilBoundary(const string &delimiter,
unsigned int *nlines, bool *eof)
bool Binc::MimePart::skipUntilBoundary(const string &delimiter,
unsigned int *nlines, bool *eof)
{
int endpos = delimiter.length();
char *delimiterqueue = 0;
@@ -360,10 +356,10 @@ static bool skipUntilBoundary(const string &delimiter,
// Need to see if this is a final one (with an additional -- at the end),
// and need to check if it is immediately followed by another boundary
// (in this case, we give up our final CRLF in its favour)
static inline void postBoundaryProcessing(bool *eof,
unsigned int *nlines,
int *boundarysize,
bool *foundendofpart)
inline void Binc::MimePart::postBoundaryProcessing(bool *eof,
unsigned int *nlines,
int *boundarysize,
bool *foundendofpart)
{
// Read two more characters. This may be CRLF, it may be "--" and
// it may be any other two characters.
@@ -430,14 +426,14 @@ static inline void postBoundaryProcessing(bool *eof,
}
}
static void parseMultipart(const string &boundary,
const string &toboundary,
bool *eof,
unsigned int *nlines,
int *boundarysize,
bool *foundendofpart,
unsigned int *bodylength,
vector<Binc::MimePart> *members)
void Binc::MimePart::parseMultipart(const string &boundary,
const string &toboundary,
bool *eof,
unsigned int *nlines,
int *boundarysize,
bool *foundendofpart,
unsigned int *bodylength,
vector<Binc::MimePart> *members)
{
MPFDEB((stderr, "BINC: ParseMultipart: boundary [%s], toboundary[%s]\n",
boundary.c_str(),
@@ -468,7 +464,7 @@ static void parseMultipart(const string &boundary,
// If parseFull returns != 0, then it encountered the multipart's
// final boundary.
int bsize = 0;
if (m.doParseFull(boundary, bsize)) {
if (m.doParseFull(mimeSource, boundary, bsize)) {
quit = true;
*boundarysize = bsize;
}
@@ -508,7 +504,7 @@ static void parseMultipart(const string &boundary,
MPFDEB((stderr, "BINC: ParseMultipart return\n"));
}
static void parseSinglePart(const string &toboundary,
void Binc::MimePart::parseSinglePart(const string &toboundary,
int *boundarysize,
unsigned int *nbodylines,
unsigned int *nlines,
@@ -591,10 +587,11 @@ static void parseSinglePart(const string &toboundary,
}
//------------------------------------------------------------------------
int Binc::MimePart::doParseFull(const string &toboundary,
int &boundarysize) const
int Binc::MimePart::doParseFull(MimeInputSource *ms, const string &toboundary,
int &boundarysize)
{
MPFDEB((stderr, "BINC: doParsefull, toboundary[%s]\n", toboundary.c_str()));
mimeSource = ms;
headerstartoffsetcrlf = mimeSource->getOffset();
// Parse the header of this mime part.
@@ -604,6 +601,7 @@ int Binc::MimePart::doParseFull(const string &toboundary,
// CRLF.
headerlength = mimeSource->getOffset() - headerstartoffsetcrlf;
bodystartoffsetcrlf = mimeSource->getOffset();
MPFDEB((stderr, "BINC: doParsefull, bodystartoffsetcrlf %d\n", bodystartoffsetcrlf));
bodylength = 0;
// Determine the type of mime part by looking at fields in the
+11 -14
View File
@@ -47,20 +47,15 @@ using namespace ::std;
#endif /* NO_NAMESPACES */
//------------------------------------------------------------------------
void Binc::MimeDocument::parseOnlyHeader(int fd) const
void Binc::MimeDocument::parseOnlyHeader(int fd)
{
if (allIsParsed || headerIsParsed)
return;
headerIsParsed = true;
if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
delete mimeSource;
mimeSource = new MimeInputSource(fd);
} else {
mimeSource->reset();
}
delete doc_mimeSource;
doc_mimeSource = new MimeInputSource(fd);
headerstartoffsetcrlf = 0;
headerlength = 0;
@@ -72,18 +67,18 @@ void Binc::MimeDocument::parseOnlyHeader(int fd) const
nlines = 0;
nbodylines = 0;
doParseOnlyHeader("");
doParseOnlyHeader(doc_mimeSource, "");
}
void Binc::MimeDocument::parseOnlyHeader(istream& s) const
void Binc::MimeDocument::parseOnlyHeader(istream& s)
{
if (allIsParsed || headerIsParsed)
return;
headerIsParsed = true;
delete mimeSource;
mimeSource = new MimeInputSourceStream(s);
delete doc_mimeSource;
doc_mimeSource = new MimeInputSourceStream(s);
headerstartoffsetcrlf = 0;
headerlength = 0;
@@ -95,12 +90,14 @@ void Binc::MimeDocument::parseOnlyHeader(istream& s) const
nlines = 0;
nbodylines = 0;
doParseOnlyHeader("");
doParseOnlyHeader(doc_mimeSource, "");
}
//------------------------------------------------------------------------
int Binc::MimePart::doParseOnlyHeader(const string &toboundary) const
int Binc::MimePart::doParseOnlyHeader(MimeInputSource *ms,
const string &toboundary)
{
mimeSource = ms;
string name;
string content;
char cqueue[4];
+1 -18
View File
@@ -51,15 +51,10 @@ using namespace ::std;
#endif /* NO_NAMESPACES */
//------------------------------------------------------------------------
void Binc::MimePart::printBody(int fd, IODevice &output,
void Binc::MimePart::printBody(IODevice &output,
unsigned int startoffset,
unsigned int length) const
{
if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
delete mimeSource;
mimeSource = new MimeInputSource(fd);
}
mimeSource->reset();
mimeSource->seek(bodystartoffsetcrlf + startoffset);
@@ -75,18 +70,6 @@ void Binc::MimePart::printBody(int fd, IODevice &output,
}
}
void Binc::MimePart::getBody(int fd, string &s,
unsigned int startoffset,
unsigned int length) const
{
if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
delete mimeSource;
mimeSource = new MimeInputSource(fd);
}
getBody(s, startoffset, length);
}
void Binc::MimePart::getBody(string &s,
unsigned int startoffset,
unsigned int length) const
-72
View File
@@ -1,72 +0,0 @@
/* -*- mode:c++;c-basic-offset:2 -*- */
/* --------------------------------------------------------------------
* Filename:
* mime-printdoc.cc
*
* Description:
* Implementation of main mime parser components
* --------------------------------------------------------------------
* Copyright 2002-2005 Andreas Aardal Hanssen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
* --------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "mime.h"
#include "mime-utils.h"
#include "mime-inputsource.h"
#include "convert.h"
#include "iodevice.h"
#include "iofactory.h"
#include <string>
#include <vector>
#include <map>
#include <exception>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#ifndef NO_NAMESPACES
using namespace ::std;
#endif /* NO_NAMESPACES */
//------------------------------------------------------------------------
void Binc::MimePart::printDoc(int fd, IODevice &output,
unsigned int startoffset,
unsigned int length) const
{
if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
delete mimeSource;
mimeSource = new MimeInputSource(fd);
}
mimeSource->reset();
mimeSource->seek(headerstartoffsetcrlf);
char c;
for (unsigned int i = 0; i < length; ++i) {
if (!mimeSource->getChar(&c))
break;
output << (char)c;
}
}
-200
View File
@@ -1,200 +0,0 @@
/* -*- mode:c++;c-basic-offset:2 -*- */
/* --------------------------------------------------------------------
* Filename:
* mime-printheader.cc
*
* Description:
* Implementation of main mime parser components
* --------------------------------------------------------------------
* Copyright 2002-2005 Andreas Aardal Hanssen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
* --------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "mime.h"
#include "mime-utils.h"
#include "mime-inputsource.h"
#include "convert.h"
#include "iodevice.h"
#include "iofactory.h"
#include <string>
#include <vector>
#include <map>
#include <exception>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#ifndef NO_NAMESPACES
using namespace ::std;
#endif /* NO_NAMESPACES */
//------------------------------------------------------------------------
void Binc::MimePart::printHeader(int fd, IODevice &output,
vector<string> headers, bool includeheaders,
unsigned int startoffset,
unsigned int length, string &store) const
{
if (!mimeSource || mimeSource->getFileDescriptor() != fd) {
delete mimeSource;
mimeSource = new MimeInputSource(fd);
}
mimeSource->seek(headerstartoffsetcrlf);
string name;
string content;
char cqueue[2];
memset(cqueue, 0, sizeof(cqueue));
bool quit = false;
char c = '\0';
unsigned int wrotebytes = 0;
unsigned int processedbytes = 0;
bool hasHeaderSeparator = false;
while (!quit) {
// read name
while (1) {
// allow EOF to end the header
if (!mimeSource->getChar(&c)) {
quit = true;
break;
}
// assume this character is part of the header name.
name += c;
// break on the first colon
if (c == ':')
break;
// break if a '\n' turned up.
if (c == '\n') {
// end of headers detected
if (name == "\r\n") {
hasHeaderSeparator = true;
quit = true;
break;
}
// put all data back in the buffer to the beginning of this
// line.
for (int i = name.length(); i >= 0; --i)
mimeSource->ungetChar();
// abort printing of header. note that in this case, the
// headers will not end with a seperate \r\n.
quit = true;
name.clear();
break;
}
}
if (quit) break;
// at this point, we have a name, that is - the start of a
// header. we'll read until the end of the header.
while (!quit) {
// allow EOF to end the header.
if (!mimeSource->getChar(&c)) {
quit = true;
break;
}
if (c == '\n') ++nlines;
// make a fifo queue of the last 4 characters.
cqueue[0] = cqueue[1];
cqueue[1] = c;
// print header
if (cqueue[0] == '\n' && cqueue[1] != '\t' && cqueue[1] != ' ') {
// it wasn't a space, so put it back as it is most likely
// the start of a header name. in any case it terminates the
// content part of this header.
mimeSource->ungetChar();
string lowername = name;
lowercase(lowername);
trim(lowername, ": \t");
bool foundMatch = false;
for (vector<string>::const_iterator i = headers.begin();
i != headers.end(); ++i) {
string nametmp = *i;
lowercase(nametmp);
if (nametmp == lowername) {
foundMatch = true;
break;
}
}
if (foundMatch == includeheaders || headers.size() == 0) {
string out = name + content;
for (string::const_iterator i = out.begin(); i != out.end(); ++i)
if (processedbytes >= startoffset && wrotebytes < length) {
if (processedbytes >= startoffset) {
store += *i;
++wrotebytes;
}
} else
++processedbytes;
}
// move on to the next header
content.clear();
name.clear();
break;
}
content += c;
}
}
if (name != "") {
string lowername = name;
lowercase(lowername);
trim(lowername, ": \t");
bool foundMatch = false;
for (vector<string>::const_iterator i = headers.begin();
i != headers.end(); ++i) {
string nametmp = *i;
lowercase(nametmp);
if (nametmp == lowername) {
foundMatch = true;
break;
}
}
if (hasHeaderSeparator || foundMatch == includeheaders || headers.size() == 0) {
string out = name + content;
for (string::const_iterator i = out.begin(); i != out.end(); ++i)
if (processedbytes >= startoffset && wrotebytes < length) {
store += *i;
++wrotebytes;
} else
++processedbytes;
}
}
}
+21 -12
View File
@@ -27,49 +27,57 @@
#include <config.h>
#endif
#include "mime.h"
#include "convert.h"
#include <string>
#include <vector>
#include <map>
#include <exception>
#include <iostream>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <string>
#include <vector>
#include <map>
#include <exception>
#include <iostream>
#ifndef NO_NAMESPACES
using namespace ::std;
#endif /* NO_NAMESPACES */
#include "mime.h"
#include "convert.h"
#include "mime-inputsource.h"
//------------------------------------------------------------------------
Binc::MimeDocument::MimeDocument(void) : MimePart()
Binc::MimeDocument::MimeDocument(void)
{
allIsParsed = false;
headerIsParsed = false;
doc_mimeSource = 0;
}
//------------------------------------------------------------------------
Binc::MimeDocument::~MimeDocument(void)
{
delete doc_mimeSource;
doc_mimeSource = 0;
}
//------------------------------------------------------------------------
void Binc::MimeDocument::clear(void) const
void Binc::MimeDocument::clear(void)
{
members.clear();
h.clear();
headerIsParsed = false;
allIsParsed = false;
delete doc_mimeSource;
doc_mimeSource = 0;
}
//------------------------------------------------------------------------
void Binc::MimePart::clear(void) const
void Binc::MimePart::clear(void)
{
members.clear();
h.clear();
mimeSource = 0;
}
//------------------------------------------------------------------------
@@ -81,6 +89,7 @@ Binc::MimePart::MimePart(void)
nlines = 0;
nbodylines = 0;
mimeSource = 0;
}
//------------------------------------------------------------------------
@@ -147,7 +156,7 @@ bool Binc::Header::getAllHeaders(const string &key, vector<HeaderItem> &dest) co
}
//------------------------------------------------------------------------
void Binc::Header::clear(void) const
void Binc::Header::clear(void)
{
content.clear();
}
+67 -23
View File
@@ -35,6 +35,10 @@
#include <stdio.h>
namespace Binc {
class MimeInputSource;
//----------------------------------------------------------------------
class HeaderItem {
private:
@@ -59,7 +63,7 @@ namespace Binc {
bool getFirstHeader(const std::string &key, HeaderItem &dest) const;
bool getAllHeaders(const std::string &key, std::vector<HeaderItem> &dest) const;
void add(const std::string &name, const std::string &content);
void clear(void) const;
void clear(void);
//--
Header(void);
@@ -106,40 +110,80 @@ namespace Binc {
inline unsigned int getBodyLength(void) const { return bodylength; }
inline unsigned int getBodyStartOffset(void) const { return bodystartoffsetcrlf; }
void printBody(int fd, Binc::IODevice &output, unsigned int startoffset, unsigned int length) const;
void getBody(int fd, std::string& s, unsigned int startoffset, unsigned int length) const;
void printBody(Binc::IODevice &output, unsigned int startoffset, unsigned int length) const;
void getBody(std::string& s, unsigned int startoffset, unsigned int length) const;
void printHeader(int fd, Binc::IODevice &output, std::vector<std::string> headers, bool includeheaders, unsigned int startoffset, unsigned int length, std::string &storage) const;
void printDoc(int fd, Binc::IODevice &output, unsigned int startoffset, unsigned int length) const;
virtual void clear(void) const;
virtual void clear(void);
const MimePart *getPart(const std::string &findpart, std::string genpart, FetchType fetchType = FetchBody) const;
virtual int doParseOnlyHeader(const std::string &toboundary) const;
virtual int doParseFull(const std::string &toboundary, int &boundarysize) const;
virtual int doParseOnlyHeader(MimeInputSource *ms,
const std::string &toboundary);
virtual int doParseFull(MimeInputSource *ms,
const std::string &toboundary, int &boundarysize);
MimePart(void);
virtual ~MimePart(void);
private:
MimeInputSource *mimeSource;
bool parseOneHeaderLine(Binc::Header *header, unsigned int *nlines);
bool skipUntilBoundary(const std::string &delimiter,
unsigned int *nlines, bool *eof);
inline void postBoundaryProcessing(bool *eof,
unsigned int *nlines,
int *boundarysize,
bool *foundendofpart);
void parseMultipart(const std::string &boundary,
const std::string &toboundary,
bool *eof,
unsigned int *nlines,
int *boundarysize,
bool *foundendofpart,
unsigned int *bodylength,
std::vector<Binc::MimePart> *members);
void parseSinglePart(const std::string &toboundary,
int *boundarysize,
unsigned int *nbodylines,
unsigned int *nlines,
bool *eof, bool *foundendofpart,
unsigned int *bodylength);
void parseHeader(Binc::Header *header, unsigned int *nlines);
void analyzeHeader(Binc::Header *header, bool *multipart,
bool *messagerfc822, std::string *subtype,
std::string *boundary);
void parseMessageRFC822(std::vector<Binc::MimePart> *members,
bool *foundendofpart,
unsigned int *bodylength,
unsigned int *nbodylines,
const std::string &toboundary);
};
//----------------------------------------------------------------------
class MimeDocument : public MimePart {
private:
mutable bool headerIsParsed;
mutable bool allIsParsed;
public:
void parseOnlyHeader(int fd) const;
void parseFull(int fd) const;
void parseOnlyHeader(std::istream& s) const;
void parseFull(std::istream& s) const;
void clear(void) const;
inline bool isHeaderParsed(void) { return headerIsParsed; }
inline bool isAllParsed(void) { return allIsParsed; }
//--
MimeDocument(void);
~MimeDocument(void);
void parseOnlyHeader(int fd);
void parseFull(int fd);
void parseOnlyHeader(std::istream& s);
void parseFull(std::istream& s);
void clear(void);
bool isHeaderParsed(void) const
{
return headerIsParsed;
}
bool isAllParsed(void) const
{
return allIsParsed;
}
private:
bool headerIsParsed;
bool allIsParsed;
MimeInputSource *doc_mimeSource;
};
};