From: Timo Heister Date: Tue, 31 May 2022 15:28:44 +0000 (-0400) Subject: vtu zlib: assert max size X-Git-Tag: v9.4.0-rc1~97^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5bc2623f2272097dde5e7b2536975dc9ef8550ed;p=dealii.git 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. --- 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 */