|
|
@ -1,4 +1,4 @@ |
|
|
|
#include "quoted_printable.hh"
|
|
|
|
#include "quoted_printable.hxx"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
@ -7,8 +7,6 @@ namespace pEpMIME |
|
|
|
namespace qp |
|
|
|
{ |
|
|
|
|
|
|
|
#define __ (-1) // invalid char -> exception!
|
|
|
|
|
|
|
|
const int8_t values[256] = { |
|
|
|
// 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
|
|
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0x00 .. 0x0F
|
|
|
@ -29,67 +27,29 @@ namespace qp |
|
|
|
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xF0 .. 0xFF
|
|
|
|
}; |
|
|
|
|
|
|
|
unsigned from_hex(char high, char low) |
|
|
|
{ |
|
|
|
const int h2 = values[(unsigned char)high]; |
|
|
|
const int l2 = values[(unsigned char)low]; |
|
|
|
|
|
|
|
if(h2<0 || l2<0) |
|
|
|
{ |
|
|
|
throw std::runtime_error(std::string("Illegal Hex sequence \"=") + high + low + "\" in QP-encoded string!"); |
|
|
|
} |
|
|
|
|
|
|
|
return h2*16u + l2; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// decodes "quoted printable"-encoded 'input', throw if illegal character found in string
|
|
|
|
std::string decode(const std::string& input) |
|
|
|
try |
|
|
|
{ |
|
|
|
std::string ret; |
|
|
|
ret.reserve( input.size() ); |
|
|
|
|
|
|
|
const char* c = input.data(); |
|
|
|
const char* const end = c + input.size(); |
|
|
|
|
|
|
|
while(c < end) |
|
|
|
{ |
|
|
|
const char ch = *c; |
|
|
|
if(ch=='=') |
|
|
|
{ |
|
|
|
++c; |
|
|
|
if(c+1>=end) |
|
|
|
{ |
|
|
|
throw std::runtime_error("Unexpected end of qp-encoded string!"); |
|
|
|
} |
|
|
|
if(*c == '\r') // soft line break
|
|
|
|
{ |
|
|
|
if(*++c == '\n') // CRLF sequence completed
|
|
|
|
{ |
|
|
|
++c; |
|
|
|
continue; // Soft Line Break: just absorb and go on.
|
|
|
|
}else{ |
|
|
|
throw std::runtime_error("Illegal sequence of Soft Line Break"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const char high = *c; |
|
|
|
++c; |
|
|
|
const char low = *c; |
|
|
|
ret += char(from_hex(high, low)); |
|
|
|
}else{ |
|
|
|
ret += ch; |
|
|
|
} |
|
|
|
|
|
|
|
++c; |
|
|
|
} |
|
|
|
|
|
|
|
auto out = std::back_inserter(ret); |
|
|
|
decode_iter(input.begin(), input.end(), out, infinity_end); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
catch(const UnexpectedEnd& ue) |
|
|
|
{ |
|
|
|
throw std::runtime_error("Unexpected end of qp-encoded string \"" + input + "\""); |
|
|
|
} |
|
|
|
catch(const IllegalHexSequence& ihs) |
|
|
|
{ |
|
|
|
throw std::runtime_error( std::string("Illegal hex sequence “=") + ihs.high + ihs.low + "” in qp-encoded string \"" + input + "\""); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// decodes "quoted printable"-encoded header line, throw if illegal character found in string
|
|
|
|
// means: no "soft line breaks", but special handling of underscores.
|
|
|
|
// TODO: use decode_iter<> here, too? Humm, don't know...
|
|
|
|
std::string decode_header(const std::string& input) |
|
|
|
{ |
|
|
|
std::string ret; |
|
|
|