diff --git a/lib/bytes.cc b/lib/bytes.cc index 12acca87..cf1729fc 100644 --- a/lib/bytes.cc +++ b/lib/bytes.cc @@ -124,12 +124,16 @@ uint8_t& Bytes::operator [] (unsigned pos) Bytes Bytes::slice(unsigned start, unsigned len) const { start += _low; - boundsCheck(start); unsigned end = start + len; - if (end > _high) + if (start >= _high) + { + /* Asking for a completely out-of-range slice --- just return zeroes. */ + return Bytes(len); + } + else if (end > _high) { /* Can't share the buffer, as we need to zero-pad the end. */ - Bytes b(end - start); + Bytes b(len); std::uninitialized_copy(cbegin()+start, cend(), b.begin()); return b; } diff --git a/lib/ibm/decoder.cc b/lib/ibm/decoder.cc index 4f35359f..088e05a5 100644 --- a/lib/ibm/decoder.cc +++ b/lib/ibm/decoder.cc @@ -20,6 +20,8 @@ SectorVector AbstractIbmDecoder::decodeToSectors(const RawRecordVector& rawRecor { const Bytes bytes = decodeFmMfm(rawrecord->data); int headerSize = skipHeaderBytes(); + if (bytes.size() < (headerSize + 1)) + continue; Bytes data = bytes.slice(headerSize, bytes.size() - headerSize); switch (data[0]) diff --git a/tests/bytes.cc b/tests/bytes.cc index 9a80dfb5..3d5631ed 100644 --- a/tests/bytes.cc +++ b/tests/bytes.cc @@ -98,6 +98,23 @@ static void test_writes() assert((b == Bytes{ 1, 2, 3, 4, 5 })); } +static void test_slice() +{ + Bytes b = {1, 2, 3}; + + Bytes bs = b.slice(1, 1); + assert((bs == Bytes{ 2 })); + + bs = b.slice(1, 2); + assert((bs == Bytes{ 2, 3 })); + + bs = b.slice(1, 3); + assert((bs == Bytes{ 2, 3, 0 })); + + bs = b.slice(4, 2); + assert((bs == Bytes{ 0, 0 })); +} + int main(int argc, const char* argv[]) { test_bounds(); @@ -105,5 +122,6 @@ int main(int argc, const char* argv[]) test_equality(); test_reads(); test_writes(); + test_slice(); return 0; }