Browse Source

simplify bodyparser PART 1

afl-fuzzing
Roker 3 years ago
parent
commit
680e8a1ab4
2 changed files with 51 additions and 20 deletions
  1. +3
    -2
      src/Makefile
  2. +48
    -18
      src/bodyparser.cc

+ 3
- 2
src/Makefile View File

@ -3,9 +3,10 @@
#CXX=c++ -Wall -O0 -std=c++14 -g -glldb -fstack-protector-all
# for AFL fuzzingtests:
CXX=afl-clang++ -Wall -O1 -std=c++14 -g -glldb \
CXX=afl-clang++ -Wall -O0 -std=c++14 -g -glldb \
-fstack-protector-all -fsanitize=address \
-fno-omit-frame-pointer -fno-optimize-sibling-calls
-fno-omit-frame-pointer -fno-optimize-sibling-calls \
-DLOG_TO_STDERR
# !FIXME!
GTEST_DIR=$(HOME)/code/googletest/


+ 48
- 18
src/bodyparser.cc View File

@ -21,18 +21,34 @@ using qi::_1;
struct ContentType
{
std::string type = "text";
std::string subtype = "plain";
std::string type;
std::string subtype;
std::vector<pEpMIME::NameValue> params;
void tolower(); // only for ASCII chars, but that's sufficient here.
void unwrap(); // reverses the wrapping of overlong (andtherefore split) parameter values.
void sanitize()
{
tolower();
if(type.empty()) { type = "text"; subtype="plain"; }
unwrap();
}
};
struct ContentDisposition
{
content_disposition_type type;
std::string filename;
};
struct Content
{
Content(const HeaderSection& headers);
ContentType type;
ContentDisposition dispo;
std::string transfer_encoding;
};
struct Rfc2231ParamName
{
std::string name;
@ -170,7 +186,25 @@ std::ostream& operator<<(std::ostream& o, const ContentType& ct)
return o << "CT:{" << ct.type << "/" << ct.subtype << ". params=" << ct.params << " } ";
}
Content::Content(HeaderSections& headers)
{
const std::string cts = header_value(headers, "content-type").to_string();
auto begin = cts.cbegin();
const bool okay = qi::parse(begin, cts.cend(), content_type, t);
if(!okay)
{
LOG << "Cannot parse \"" + std::string{cts} + "\" as ContentType.\n";
}
LOG << "<<< CT raw: " << ct << ">>>\n";
ct.sanitize();
LOG << "<<< CT san: " << ct << ">>>\n";
const std::string cds = header_value(headers, "content-disposition").to_string();
}
namespace pEpMIME
{
@ -257,7 +291,13 @@ char* create_string(const BodyLines& body, const sv& charset, Decoder decoder)
void add_attachment(message* msg, const BodyLines& body, const ContentType& ct, Decoder decoder)
{
throw "Unimplemented!";
size_t decoded_size = 0;
char* decoded = decoder(body, decoded_size);
bloblist_t* bl = bloblist_add(msg->attachments, decoded, decoded_size, (ct.type + '/' + ct.subtype).c_str(), "dummy.bin");
if(msg->attachments==nullptr)
{
msg->attachments = bl;
}
}
@ -265,27 +305,17 @@ void add_attachment(message* msg, const BodyLines& body, const ContentType& ct,
void parse_body(message* msg, const HeaderSection& headers, const BodyLines& body)
{
const std::string mime_version = header_value(headers, "mime-version").to_string();
const std::string cts = header_value(headers, "content-type").to_string();
ContentType ct;
auto begin = cts.cbegin();
const bool okay = qi::parse(begin, cts.cend(), content_type, ct);
if(!okay)
{
LOG << "Cannot parse \"" + std::string{cts} + "\" as ContentType.\n";
}
LOG << "<<< CT raw: " << ct << ">>>\n";
ct.sanitize();
LOG << "<<< CT san: " << ct << ">>>\n";
Content c(headers);
if( mime_version == "1.0" ) // TODO: According to RFC 2048 there can be comments in the header field value. -.-
{
// TODO: for whatever reason "string_view cts" does not work with qi::parse(). WTF!
if(ct.type == "text")
if(c.type.type == "text")
{
const sv charset = header_value( ct.params, "charset" );
Decoder decoder = getDecoder( header_value( headers, "content-transfer-encoding" ) );
if(ct.subtype == "plain")
if(c.type.subtype == "plain")
{
// put it in msg->longmsg
msg->longmsg = create_string(body, charset, decoder);


Loading…
Cancel
Save