From 5bc2623f2272097dde5e7b2536975dc9ef8550ed Mon Sep 17 00:00:00 2001 From: Timo Heister Date: Tue, 31 May 2022 11:28:44 -0400 Subject: [PATCH] vtu zlib: assert max size We only support VTU output where each compressed section (on a single MPI rank) is less than 4GB. This is a reasonable limit, but we should assert this instead of writing corrupted data. --- source/base/data_out_base.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/source/base/data_out_base.cc b/source/base/data_out_base.cc index bfa770c2eb..e1712365b3 100644 --- a/source/base/data_out_base.cc +++ b/source/base/data_out_base.cc @@ -117,15 +117,29 @@ namespace { if (data.size() != 0) { + const std::size_t uncompressed_size = (data.size() * sizeof(T)); + + // While zlib's compress2 uses unsigned long (which is 64bits + // on Linux), the vtu compression header stores the block size + // as an uint32_t (see below). While we could implement + // writing several smaller blocks, we haven't done that. Let's + // trigger an error for the user instead: + AssertThrow(uncompressed_size <= std::numeric_limits::max(), + ExcNotImplemented()); + // allocate a buffer for compressing data and do so - auto compressed_data_length = compressBound(data.size() * sizeof(T)); + auto compressed_data_length = compressBound(uncompressed_size); + AssertThrow(compressed_data_length <= + std::numeric_limits::max(), + ExcNotImplemented()); + std::vector compressed_data(compressed_data_length); int err = compress2(&compressed_data[0], &compressed_data_length, reinterpret_cast(data.data()), - data.size() * sizeof(T), + uncompressed_size, get_zlib_compression_level(flags.compression_level)); (void)err; Assert(err == Z_OK, ExcInternalError()); @@ -135,10 +149,9 @@ namespace // now encode the compression header const uint32_t compression_header[4] = { - 1, /* number of blocks */ - static_cast(data.size() * sizeof(T)), /* size of block */ - static_cast(data.size() * - sizeof(T)), /* size of last block */ + 1, /* number of blocks */ + static_cast(uncompressed_size), /* size of block */ + static_cast(uncompressed_size), /* size of last block */ static_cast( compressed_data_length)}; /* list of compressed sizes of blocks */ -- 2.39.5