Commit 225c5afb authored by Paal Kvamme's avatar Paal Kvamme
Browse files

More consistency checks on file open.

parent 51e03bee
Pipeline #31180 passed with stages
in 19 minutes and 16 seconds
......@@ -84,8 +84,16 @@ struct TmpLookupEntry
std::vector<std::uint64_t>
LookupTable::calcLookupSize(
const std::vector<std::uint64_t>& lookup,
std::int64_t eof, std::int64_t maxsize)
std::int64_t eof, std::int64_t maxsize,
bool *return_file_truncated,
bool *return_bricks_overlap)
{
// [out] arguments
if (return_file_truncated != nullptr)
*return_file_truncated = false;
if (return_bricks_overlap != nullptr)
*return_bricks_overlap = false;
std::vector<TmpLookupEntry> entries;
std::uint64_t ord = 0;
const std::uint64_t codeshift(56);
......@@ -110,13 +118,31 @@ LookupTable::calcLookupSize(
return a.offset < b.offset;
});
// Technically I could also check the end of the last block, but
// that only works for uncompressed and only if maxsize is known.
//minimum_file_eof = entries.back().offset;
if (eof != 0 && !entries.empty() && entries.back().offset >= eof)
if (return_file_truncated != nullptr)
*return_file_truncated = true;
// The end of block i is the start of block i+1,
// except the last block which ends at EOF, just use a huge number.
// And except all blocks that are not real (i.e. offset 0)
// which should all end at 0 as well. For consistency,
for (auto it = entries.begin() + 1; it < entries.end(); ++it)
if ((it-1)->offset != 0)
for (auto it = entries.begin() + 1; it < entries.end(); ++it) {
if ((it-1)->offset != 0) {
if ((it-1)->offset == it->offset) {
if (return_bricks_overlap != nullptr)
*return_bricks_overlap = true;
// TODO-Low: This is currently a fatal error. It might later
// be allowed for testing purposes to have the same block
// pointed to by multiple entries. In that case more work is
// needed to compute endpos.
}
(it-1)->endpos = it->offset;
}
}
entries.back().endpos = eof ? eof : std::numeric_limits<std::int64_t>::max();
std::sort(entries.begin(), entries.end(),
......@@ -127,7 +153,7 @@ LookupTable::calcLookupSize(
if (eof != 0 && maxsize != 0) {
for (auto it = entries.begin(); it < entries.end(); ++it) {
// End can neither go past eof nor indicate a size > maxsize.
// Note that maxsize cannot be max for its size; that will overflow.
// Note that maxsize cannot be max for its type; that will overflow.
// TODO-Low decide on unsigned or signed, not a mix.
it->endpos = std::min(it->endpos, std::min((std::uint64_t)eof, it->offset + (std::uint64_t)maxsize));
// If size appears negative then make it zero.
......
......@@ -113,7 +113,9 @@ public:
public:
static std::vector<std::uint64_t> calcLookupSize(
const std::vector<std::uint64_t>& lookup,
std::int64_t eof, std::int64_t maxsize);
std::int64_t eof, std::int64_t maxsize,
bool *return_file_truncated,
bool *return_bricks_overlap);
static LutInfo getAlphaFilePosition(
std::int64_t i, std::int64_t j, std::int64_t lod,
......
......@@ -1358,7 +1358,14 @@ LookupTableV0Access::read(const std::shared_ptr<FileADT>& file, std::int64_t off
file->xx_read(this->_lookup.data(), offset, size);
byteswap();
// TODO-Low can I get maxsize here as well?
this->_lookend = LookupTable::calcLookupSize(this->_lookup, file->xx_eof(), 0);
bool file_truncated = false;
bool bricks_overlap = false;
this->_lookend = LookupTable::calcLookupSize(this->_lookup, file->xx_eof(), 0,
&file_truncated, &bricks_overlap);
if (file_truncated)
throw OpenZGY::Errors::ZgyFormatError("The ZGY file is truncated.");
if (bricks_overlap)
throw OpenZGY::Errors::ZgyFormatError("The ZGY file is corrupt. Bricks overlap.");
}
void
......@@ -1612,15 +1619,6 @@ InfoHeaderV2Access::calculate_write()
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
struct TmpLookupEntry
{
std::uint64_t offset;
std::uint64_t endpos;
std::uint64_t type;
std::uint64_t ordinal;
TmpLookupEntry() : offset(0), endpos(0), type(0), ordinal(0) {}
};
ZgyInternalMeta::ZgyInternalMeta()
: _is_bad(false)
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment