diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-02-18 17:17:06 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-02-18 17:27:29 +0300 |
commit | 2c12c9b61e5081a98b9ba40d9f8c7d9f63fc9725 (patch) | |
tree | 52d890b75eac2e6d47c1ec8b739d9fc5de41961c /source/blender/blenkernel/intern/library_query.c | |
parent | a0d0d37ecd9f9d0b6503f89f9587ad44eeab43ca (diff) |
ID management: forbid refcount of used IDs when user ID is outside of Main.
This is related to T61660, but actually does not fix that specific issue
(which is even worse - outside-of-Main ID using inside-of-Main IDs... yuck).
Diffstat (limited to 'source/blender/blenkernel/intern/library_query.c')
-rw-r--r-- | source/blender/blenkernel/intern/library_query.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 04c393ba733..c9c223c8724 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -90,7 +90,10 @@ if (!((_data)->status & IDWALK_STOP)) { \ const int _flag = (_data)->flag; \ ID *old_id = *(id_pp); \ - const int callback_return = (_data)->callback((_data)->user_data, (_data)->self_id, id_pp, _cb_flag | (_data)->cb_flag); \ + const int callback_return = (_data)->callback((_data)->user_data, \ + (_data)->self_id, \ + id_pp, \ + (_cb_flag | (_data)->cb_flag) & ~(_data)->cb_flag_clear); \ if (_flag & IDWALK_READONLY) { \ BLI_assert(*(id_pp) == old_id); \ } \ @@ -131,6 +134,7 @@ typedef struct LibraryForeachIDData { ID *self_id; int flag; int cb_flag; + int cb_flag_clear; LibraryIDLinkCallback callback; void *user_data; int status; @@ -369,6 +373,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) { data.self_id = id; data.cb_flag = ID_IS_LINKED(id) ? IDWALK_CB_INDIRECT_USAGE : 0; + /* When an ID is not in Main database, it should never refcount IDs it is using. */ + data.cb_flag_clear = (id->tag & LIB_TAG_NO_MAIN) ? IDWALK_CB_USER | IDWALK_CB_USER_ONE : 0; if (bmain != NULL && bmain->relations != NULL && (flag & IDWALK_READONLY)) { /* Note that this is minor optimization, even in worst cases (like id being an object with lots of |