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
This commit is contained in:
parent
46a2592eef
commit
c171e8b95c
Notes:
blender-bot
2023-02-14 11:35:46 +01:00
Referenced by issue #90620, UV Editing crash
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue