[Bf-blender-cvs] [c171e8b95c0] master: Fix T90620: Ignore missing UV data caused by corrupt .blend file

Chris Blackbourn noreply at git.blender.org
Thu Jul 21 05:24:51 CEST 2022


Commit: c171e8b95c0035eb92d2dcec6e9d82e094954d84
Author: Chris Blackbourn
Date:   Thu Jul 21 15:15:38 2022 +1200
Branches: master
https://developer.blender.org/rBc171e8b95c0035eb92d2dcec6e9d82e094954d84

Fix T90620: Ignore missing UV data caused by corrupt .blend file

Add crash protection and partial recovery for corrupt .blend files,
particularly for missing UV data.

Differential Revision: https://developer.blender.org/D15489

===================================================================

M	source/blender/blenkernel/intern/customdata.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 277218033e9..b990ccbec80 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -4443,9 +4443,48 @@ bool CustomData_verify_versions(CustomData *data, int index)
   return keeplayer;
 }
 
+static bool CustomData_layer_ensure_data_exists(CustomDataLayer *layer, size_t count)
+{
+  BLI_assert(layer);
+  const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+  BLI_assert(typeInfo);
+
+  if (layer->data || count == 0) {
+    return false;
+  }
+
+  switch (layer->type) {
+    /* When more instances of corrupt files are found, add them here. */
+    case CD_PROP_BOOL: /* See T84935. */
+    case CD_MLOOPUV:   /* See T90620. */
+      layer->data = MEM_calloc_arrayN(count, typeInfo->size, layerType_getName(layer->type));
+      BLI_assert(layer->data);
+      if (typeInfo->set_default) {
+        typeInfo->set_default(layer->data, count);
+      }
+      return true;
+      break;
+
+    default:
+      /* Log an error so we can collect instances of bad files. */
+      CLOG_ERROR(&LOG, "CustomDataLayer->data is NULL for type %d.", layer->type);
+      break;
+  }
+  return false;
+}
+
 bool CustomData_layer_validate(CustomDataLayer *layer, const uint totitems, const bool do_fixes)
 {
+  BLI_assert(layer);
   const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+  BLI_assert(typeInfo);
+
+  if (do_fixes) {
+    CustomData_layer_ensure_data_exists(layer, totitems);
+  }
+
+  BLI_assert((totitems == 0) || layer->data);
+  BLI_assert(MEM_allocN_len(layer->data) >= totitems * typeInfo->size);
 
   if (typeInfo->validate != nullptr) {
     return typeInfo->validate(layer->data, totitems, do_fixes);
@@ -5206,16 +5245,15 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
 
     if (CustomData_verify_versions(data, i)) {
       BLO_read_data_address(reader, &layer->data);
-      if (layer->data == nullptr && count > 0 && layer->type == CD_PROP_BOOL) {
-        /* Usually this should never happen, except when a custom data layer has not been written
-         * to a file correctly. */
-        CLOG_WARN(&LOG, "Reallocating custom data layer that was not saved correctly.");
-        const LayerTypeInfo *info = layerType_getInfo(layer->type);
-        layer->data = MEM_calloc_arrayN((size_t)count, info->size, layerType_getName(layer->type));
-        if (info->set_default) {
-          info->set_default(layer->data, count);
-        }
+      if (CustomData_layer_ensure_data_exists(layer, count)) {
+        /* Under normal operations, this shouldn't happen, but...
+         * For a CD_PROP_BOOL example, see T84935.
+         * For a CD_MLOOPUV example, see T90620. */
+        CLOG_WARN(&LOG,
+                  "Allocated custom data layer that was not saved correctly for layer->type = %d.",
+                  layer->type);
       }
+
       if (layer->type == CD_MDISPS) {
         blend_read_mdisps(
             reader, count, static_cast<MDisps *>(layer->data), layer->flag & CD_FLAG_EXTERNAL);



More information about the Bf-blender-cvs mailing list