Browse Source

implement qp::encode() and qp::encode_header()

afl-fuzzing
Roker 3 years ago
parent
commit
3b3e2441ff
2 changed files with 77 additions and 7 deletions
  1. +73
    -6
      src/quoted_printable.cc
  2. +4
    -1
      src/quoted_printable.hh

+ 73
- 6
src/quoted_printable.cc View File

@ -6,7 +6,6 @@ namespace pEpMIME
{
namespace qp
{
const int8_t values[256] = {
// 1 2 3 4 5 6 7 8 9 A B C D E F
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0x00 .. 0x0F
@ -27,6 +26,8 @@ namespace qp
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xF0 .. 0xFF
};
const char* const hexdigit = "0123456789ABCDEF";
// decodes "quoted printable"-encoded 'input', throw if illegal character found in string
std::string decode(const std::string& input)
try
@ -94,12 +95,78 @@ std::string decode_header(const std::string& input)
}
std::string encode(const std::string& input, int line_length, const std::string& delimiter)
std::string encode(const std::string& input)
{
std::string ret;
ret.reserve( input.size() );
throw "TODO!";
std::string ret;
ret.reserve( input.size() );
const unsigned max_u = input.size() - 1;
unsigned line_length = 0;
for(std::size_t u=0; u<input.size(); ++u)
{
unsigned char c = input[u];
if(c == '\r')
{
if(u<max_u && input[u+1]=='\n') // hard line break
{
ret += "\r\n";
++u;
line_length = 0;
}else{
ret += "=0D";
line_length+=3;
}
}else if(c == '=' || c<' ' || c>126)
{
char escape[] = { '=', hexdigit[c>>4], hexdigit[c & 0xF] };
ret.append(escape, escape+3);
line_length+=3;
}else{
ret += c;
++line_length;
}
if(line_length > MaxLineLength && u<max_u)
{
ret += "=\r\n";
line_length = 0;
}
}
return ret;
}
std::string encode_header(const std::string& input)
{
std::string ret{"=?UTF-8?Q?"};
ret.reserve( input.size() + 16);
static const unsigned max_line_len = 72 - 10 - 2; // 10 chars for QP header, 2 chars for QP footer
unsigned line_length = ret.size();
for(std::size_t u=0; u<input.size(); ++u)
{
if(line_length > max_line_len)
{
ret += "?=\r\n =?UTF-8?Q?";
line_length = 10;
}
unsigned char c = input[u];
if(c == '=' || c=='?' || c<' ' || c>126)
{
char escape[] = { '=', hexdigit[c>>4], hexdigit[c & 0xF] };
ret.append(escape, escape+3);
line_length+=3;
}else if(c==' ')
{
ret += '_';
++line_length;
}
}
return ret;
}
} // end of namespace pEpMIME::qp


+ 4
- 1
src/quoted_printable.hh View File

@ -8,11 +8,14 @@ namespace pEpMIME
namespace qp
{
constexpr const unsigned MaxLineLength = 76;
// Decodes "quoted printable"-encoded 'input', throw std::runtime_error if an illegal character found in string
std::string decode(const std::string& input);
// Encodes into "quoted printable" encoding, with optional line breaks
std::string encode(const std::string& input, int line_length=-1, const std::string& delimiter = "\r\n");
std::string encode(const std::string& input);
///////////////////////////////////////
// Low-level interface, necessary to use base64-encoding also from C


Loading…
Cancel
Save