Browse Source

make qp_header_encoding more robust. add unittest_subject and found a strange bug. :-(

afl-fuzzing
Roker 3 years ago
parent
commit
e3511b829e
3 changed files with 88 additions and 6 deletions
  1. +1
    -1
      src/Makefile
  2. +30
    -5
      src/quoted_printable.cc
  3. +57
    -0
      src/unittest_subject.cc

+ 1
- 1
src/Makefile View File

@ -16,7 +16,7 @@ libpEpMIME.a: pEpMIME.o pEpMIME_internal.o rules.o bodyparser.o \
unittests: unittest_mime.o unittest_nfc.o unittest_timestamp.o \
unittest_stringcase.o unittest_toutf8.o unittest_address.o \
unittest_rule.o \
unittest_rule.o unittest_subject.o \
gtest-all.o gtest_main.o libpEpMIME.a
${CXX} -L${HOME}/local/lib/ -o $@ $^ -lpEpAdapter -lpEpEngine -lpthread


+ 30
- 5
src/quoted_printable.cc View File

@ -28,6 +28,28 @@ namespace qp
const char* const hexdigit = "0123456789ABCDEF";
static const int8_t OK = 0;
const int8_t allowed[256] = {
// 1 2 3 4 5 6 7 8 9 A B C D E F
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0x00 .. 0x0F
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0x10 .. 0x1F
__, OK, __, __, OK, __, __, __, __, __, __, __, __, OK, OK, OK, // 0x20 .. 0x2F
OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, __, __, __, __, __, __, // 0x30 .. 0x3F 0x3D = '='
__, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, // 0x40 .. 0x4F
OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, __, __, __, OK, __, // 0x50 .. 0x5F
__, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, // 0x60 .. 0x6F
OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, __, // 0x70 .. 0x7F
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0x80 .. 0x8F
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0x90 .. 0x9F
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xA0 .. 0xAF
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xB0 .. 0xBF
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xC0 .. 0xCF
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xD0 .. 0xDF
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xE0 .. 0xEF
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xF0 .. 0xFF
};
// decodes "quoted printable"-encoded 'input', throw if illegal character found in string
std::string decode(const std::string& input)
try
@ -153,17 +175,20 @@ std::string encode_header(const std::string& input)
}
unsigned char c = input[u];
if(c == '=' || c=='?' || c<' ' || c>126)
if(allowed[c]==OK)
{
char escape[] = { '=', hexdigit[c>>4], hexdigit[c & 0xF] };
ret.append(escape, escape+3);
line_length+=3;
ret += char(c);
++line_length;
}else if(c==' ')
{
ret += '_';
++line_length;
}else
{
char escape[] = { '=', hexdigit[c>>4], hexdigit[c & 0xF] };
ret.append(escape, escape+3);
line_length+=3;
}
}
return ret;


+ 57
- 0
src/unittest_subject.cc View File

@ -0,0 +1,57 @@
#include "pEpMIME.hh"
#include <pEp/message.h>
#include <time.h>
#include <gtest/gtest.h>
namespace
{
struct TestEntry
{
std::string encoded;
std::string decoded;
};
std::ostream& operator<<(std::ostream& o, const TestEntry& t)
{
return o << " encoded=\"" << t.encoded << "\", decoded=\"" << t.decoded << "\" ";
}
const std::vector<TestEntry> testValues =
{
{"=?UTF-8?B?TcO2bGxlciDDnGJlcg==?=", "Möller Über"},
{"=?UTF-8?Q?M=C3=B6ller_=C3=9Cber?=", "Möller Über"},
{"=?UTF-8?Q?Hallo_Das_ist_nur_ein_Test_f=c3=bcr_eine_lange_Subject-Ze?=\r\n"
" =?UTF-8?Q?ile=2c_die_umgebrochen_wird=2c_da_sie_eben_viel_zu_l=c3=a4nglich_?=\r\n"
" =?UTF-8?Q?geworden_ist=2e?=",
"Hallo Das ist nur ein Test für eine lange Subject-Ze"
"ile, die umgebrochen wird, da sie eben viel zu länglich "
"geworden ist."},
};
} // end of anonymous namespace
class SubjectParserTest : public ::testing::TestWithParam<TestEntry>
{
// intentionally left blank
};
INSTANTIATE_TEST_CASE_P(SubjectParserTestInstance, SubjectParserTest, testing::ValuesIn(testValues) );
TEST_P( SubjectParserTest, Meh )
{
const auto& v = GetParam();
const std::string mime_msg =
"Subject: " + v.encoded + "\r\n"
"From: example@pep.lol\r\n"
"\r\n"
"Hallo Welt.\r\n"
"\r\n";
message* m = pEpMIME::parse_message( mime_msg.c_str(), mime_msg.size() );
ASSERT_NE( m , nullptr );
EXPECT_EQ( m->shortmsg , v.decoded );
free_message(m);
}

Loading…
Cancel
Save