]> https://gitweb.dealii.org/ - dealii.git/commitdiff
vtu zlib: assert max size 13875/head
authorTimo Heister <timo.heister@gmail.com>
Tue, 31 May 2022 15:28:44 +0000 (11:28 -0400)
committerTimo Heister <timo.heister@gmail.com>
Tue, 31 May 2022 15:28:44 +0000 (11:28 -0400)
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

index bfa770c2eba7c7a3f8de4e861e8821a796f9aac7..e1712365b30bb1247c068f54120c254567ab1b59 100644 (file)
@@ -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<uint32_t>::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<uint32_t>::max(),
+                    ExcNotImplemented());
+
         std::vector<unsigned char> compressed_data(compressed_data_length);
 
         int err =
           compress2(&compressed_data[0],
                     &compressed_data_length,
                     reinterpret_cast<const Bytef *>(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<uint32_t>(data.size() * sizeof(T)), /* size of block */
-          static_cast<uint32_t>(data.size() *
-                                sizeof(T)), /* size of last block */
+          1,                                        /* number of blocks */
+          static_cast<uint32_t>(uncompressed_size), /* size of block */
+          static_cast<uint32_t>(uncompressed_size), /* size of last block */
           static_cast<uint32_t>(
             compressed_data_length)}; /* list of compressed sizes of blocks */
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.