Core: remove support for writing MemFile undo steps as .blend files

In many modes, Blender uses the `MemFile` undo step, which serializes all DNA
data in RAM almost as if writing a .blend file. For auto-save, Blender used to
write the last `MemFile` undo step to disk because that was faster serializing
all of DNA again. Furthermore, saving the `quit.blend` file when closing Blender
also used this.

This functionality is now removed in preparate for supporting implicit sharing
in the undo system (#106903). Auto-save and saving the quit.blend file now use
regular file saving.

The removal of this feature and its implications have also been discussed here:
https://devtalk.blender.org/t/remove-support-for-saving-memfile-undo-steps-as-blend-files-proposal/33544
This commit is contained in:
Jacques Lucke
2024-02-29 17:04:36 +01:00
parent e90f5d03c4
commit efb511a76d
4 changed files with 15 additions and 80 deletions

View File

@@ -94,11 +94,5 @@ void BLO_memfile_clear_future(MemFile *memfile);
/* Utilities. */
Main *BLO_memfile_main_get(MemFile *memfile, Main *bmain, Scene **r_scene);
/**
* Saves .blend using undo buffer.
*
* \return success.
*/
bool BLO_memfile_write_file(MemFile *memfile, const char *filepath);
FileReader *BLO_memfile_new_filereader(MemFile *memfile, int undo_direction);

View File

@@ -175,61 +175,6 @@ Main *BLO_memfile_main_get(MemFile *memfile, Main *bmain, Scene **r_scene)
return bmain_undo;
}
bool BLO_memfile_write_file(MemFile *memfile, const char *filepath)
{
MemFileChunk *chunk;
int file, oflags;
/* NOTE: This is currently used for auto-save and `quit.blend`,
* where _not_ following symbolic-links is OK,
* however if this is ever executed explicitly by the user,
* we may want to allow writing to symbolic-links. */
oflags = O_BINARY | O_WRONLY | O_CREAT | O_TRUNC;
#ifdef O_NOFOLLOW
/* use O_NOFOLLOW to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
oflags |= O_NOFOLLOW;
#else
/* TODO(sergey): How to deal with symlinks on windows? */
# ifndef _MSC_VER
# warning "Symbolic links will be followed on undo save, possibly causing CVE-2008-1103"
# endif
#endif
file = BLI_open(filepath, oflags, 0666);
if (file == -1) {
fprintf(stderr,
"Unable to save '%s': %s\n",
filepath,
errno ? strerror(errno) : "Unknown error opening file");
return false;
}
for (chunk = static_cast<MemFileChunk *>(memfile->chunks.first); chunk;
chunk = static_cast<MemFileChunk *>(chunk->next))
{
#ifdef _WIN32
if (size_t(write(file, chunk->buf, uint(chunk->size))) != chunk->size)
#else
if (size_t(write(file, chunk->buf, chunk->size)) != chunk->size)
#endif
{
break;
}
}
close(file);
if (chunk) {
fprintf(stderr,
"Unable to save '%s': %s\n",
filepath,
errno ? strerror(errno) : "Unknown error writing file");
return false;
}
return true;
}
static int64_t undo_read(FileReader *reader, void *buffer, size_t size)
{
UndoReader *undo = (UndoReader *)reader;

View File

@@ -2115,9 +2115,12 @@ static bool wm_autosave_write_try(Main *bmain, wmWindowManager *wm)
wm_autosave_location(filepath);
if (MemFile *memfile = ED_undosys_stack_memfile_get_if_active(wm->undo_stack)) {
/* Fast save of last undo-buffer, now with UI. */
BLO_memfile_write_file(memfile, filepath);
/* Technically, we could always just save here, but that would cause performance regressions
* compared to when the #MemFile undo step was used for saving undo-steps. So for now just skip
* auto-save when we are in a mode where auto-save wouldn't have worked previously anyway. This
* check can be removed once the performance regressions have been solved. */
if (ED_undosys_stack_memfile_get_if_active(wm->undo_stack) != nullptr) {
WM_autosave_write(wm, bmain);
return true;
}
if ((U.uiflag & USER_GLOBALUNDO) == 0) {

View File

@@ -471,26 +471,19 @@ void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_
/* NOTE: same code copied in `wm_files.cc`. */
if (C && wm) {
if (do_user_exit_actions) {
/* save the undo state as quit.blend */
/* Save quit.blend. */
Main *bmain = CTX_data_main(C);
char filepath[FILE_MAX];
BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
MemFile *undo_memfile = wm->undo_stack ?
ED_undosys_stack_memfile_get_if_active(wm->undo_stack) :
nullptr;
/* When true, the `undo_memfile` doesn't contain all information necessary
* for writing and up to date blend file. */
const bool is_memfile_outdated = ED_editors_flush_edits(bmain);
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
if (undo_memfile && !is_memfile_outdated) {
BLO_memfile_write_file(undo_memfile, filepath);
BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
ED_editors_flush_edits(bmain);
BlendFileWriteParams blend_file_write_params{};
if (BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr)) {
printf("Saved session recovery to \"%s\"\n", filepath);
}
else {
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
BlendFileWriteParams blend_file_write_params{};
BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr);
}
printf("Saved session recovery to \"%s\"\n", filepath);
}
WM_jobs_kill_all(wm);