Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Blackbourn <chrisbblend@gmail.com>2022-07-21 06:15:38 +0300
committerChris Blackbourn <chrisbblend@gmail.com>2022-07-21 06:24:38 +0300
commitc171e8b95c0035eb92d2dcec6e9d82e094954d84 (patch)
tree02315a8643fe422550e02e29d38912b80b029684 /source/blender/blenkernel/intern/customdata.cc
parent46a2592eef90782bea6124767c072f275330bd00 (diff)
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
Diffstat (limited to 'source/blender/blenkernel/intern/customdata.cc')
-rw-r--r--source/blender/blenkernel/intern/customdata.cc56
1 files changed, 47 insertions, 9 deletions
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);