Browse Source

be more robust: illegal QP-sequences will no longer throw exceptions. *sigh*

afl-fuzzing
Roker 3 years ago
parent
commit
49ad7345ca
2 changed files with 53 additions and 33 deletions
  1. +11
    -2
      src/quoted_printable.cc
  2. +42
    -31
      src/quoted_printable.hxx

+ 11
- 2
src/quoted_printable.cc View File

@ -91,13 +91,22 @@ std::string decode_header(const std::string& input)
++c;
if(c+1>=end)
{
throw std::runtime_error("Unexpected end of qp-encoded string!");
// throw std::runtime_error("Unexpected end of qp-encoded string!");
ret += '=';
continue;
}
const char high = *c;
++c;
const char low = *c;
ret += char(from_hex(high, low));
try{
ret += char(from_hex(high, low));
}catch(const IllegalHexSequence& h)
{
ret += '=';
ret += high;
ret += low;
}
break;
}


+ 42
- 31
src/quoted_printable.hxx View File

@ -44,47 +44,58 @@ namespace qp
}
template<class Iter>
int fetch(Iter& curr, Iter end)
{
if(curr == end)
return -1;
const int ret = *curr;
++curr;
return ret;
}
template<class OutIter, class OutIter2>
void copy_out(OutIter& out, OutIter2 out_end, char c)
{
if(out == out_end)
{
throw std::runtime_error("Output buffer for QP-decoding is too small.");
}
*out = c;
++out;
}
template<class InIter, class OutIter, class OutIter2>
void decode_iter(InIter begin, InIter end, OutIter& out, OutIter2 out_end)
{
InIter c = begin;
while(c != end)
InIter curr = begin;
while(curr != end)
{
const char ch = *c;
const char ch = fetch(curr, end);
if(ch=='=')
{
++c;
if(c==end) throw UnexpectedEnd{};
if(*c == '\r') // soft line break
{
++c;
if(c==end) throw UnexpectedEnd{};
const int first = fetch(curr, end);
const int second = fetch(curr, end);
if(*c == '\n') // CRLF sequence completed
{
++c;
continue; // Soft Line Break: just absorb and go on.
}else{
throw IllegalHexSequence{'\r', *c};
}
if(first == '\r' && second == '\n') // soft line break
{
continue; // Soft Line Break: just absorb and go on.
}
try{
copy_out(out, out_end, char(from_hex((char)first, (char)second)) );
}catch(const IllegalHexSequence& e)
{
copy_out(out, out_end, '=');
if(first>=0) copy_out(out, out_end, first);
if(second>=0) copy_out(out, out_end, second);
}
const char high = *c;
++c;
if(c==end) throw std::runtime_error("Unexpected end of qp-encoded string!");
const char low = *c;
if(out == out_end) throw std::runtime_error("Output buffer too small.");
*out = char(from_hex(high, low));
++out;
}else{
if(out == out_end) throw std::runtime_error("Output buffer too small.");
*out = ch;
++out;
copy_out(out, out_end, ch );
}
++c;
}
}


Loading…
Cancel
Save