Fix #120466: Crash when opening file with inactive asset browser

Issue wasn't directly related to material assets or the shader editor.

Simpler steps to reproduce:
- Open Asset Browser
- Change Asset Browser to different editor type
- Open new file (Ctrl+N)

The asset browser would remain in storage as inactive editor, including
pointers to the asset system. When opening a new file, the asset system
would get freed before the asset browser, which would then access
dangling pointers as part of its own freeing process.

Part of the issue is that `SpaceType.exit()` doesn't get called in this
case, which would remove the asset system references before the asset
system is freed. Will address this in a follow up in main, but best to
not depend on the `exit()` callback too much. Easy to do here.
This commit is contained in:
Julian Eisel
2024-06-10 16:21:19 +02:00
parent a309b4c8d1
commit 83edd748a2
3 changed files with 17 additions and 1 deletions

View File

@@ -241,6 +241,14 @@ std::string AS_asset_library_find_suitable_root_path_from_path(blender::StringRe
*/
std::string AS_asset_library_find_suitable_root_path_from_main(const Main *bmain);
/**
* Checks if the asset library service is in a usable state, i.e. after initializing and before
* calling #AS_asset_libraries_exit(). Only needed in rare cases, e.g. when it's known that asset
* library data may be accessed via dangling pointers on file exit, see #120466. Would be nicer to
* clear the pointers instead, but not worth the extra logic for such a corner case.
*/
bool AS_asset_libraries_available();
/**
* Force clearing of all asset library data. After calling this, new asset libraries can be loaded
* just as usual using #AS_asset_library_load(), no init or other setup is needed.

View File

@@ -35,6 +35,12 @@ using namespace blender::asset_system;
bool AssetLibrary::save_catalogs_when_file_is_saved = true;
bool AS_asset_libraries_available()
{
const AssetLibraryService *service = AssetLibraryService::get();
return service != nullptr;
}
void AS_asset_libraries_exit()
{
/* NOTE: Can probably removed once #WITH_DESTROY_VIA_LOAD_HANDLER gets enabled by default. */

View File

@@ -1456,7 +1456,9 @@ static void filelist_direntryarr_free(FileDirEntryArr *array)
static void filelist_intern_entry_free(FileList *filelist, FileListInternEntry *entry)
{
if (entry->asset) {
/* Asset system storage might be cleared already on file exit. Asset library
* pointers are dangling then, so don't access (#120466). */
if (AS_asset_libraries_available() && entry->asset) {
BLI_assert(filelist->asset_library);
filelist->asset_library->remove_asset(*entry->asset);
}