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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -39,9 +39,6 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "address.h"
|
||||
//#include "depot.h"
|
||||
|
||||
namespace Binc {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user