diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-03-19 16:17:59 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-03-31 21:40:37 +0300 |
commit | 651b8fb14eb6ee5cbfa98bffe80a966a0753b14e (patch) | |
tree | 2281978509d82a25fb5fbf586f34335e3606442d /source/blender/blenloader/intern/undofile.c | |
parent | 91d0825b5556150c017dad767f7971bb6a731aec (diff) |
Undo: unified undo system w/ linear history
- Use a single undo history for all operations.
- UndoType's are registered and poll the context to check if they
should be used when performing an undo push.
- Mode switching is used to ensure the state is correct before
undo data is restored.
- Some undo types accumulate changes (image & text editing)
others store the state multiple times (with de-duplication).
This is supported by checking UndoStack.mode `ACCUMULATE` / `STORE`.
- Each undo step stores ID datablocks they use with utilities to help
manage restoring correct ID's.
Needed since global undo is now mixed with other modes undo.
- Currently performs each undo step when going up/down history
Previously this wasn't done, making history fail in some cases.
This can be optimized to skip some combinations of undo steps.
grease-pencil is an exception which has not been updated
since it integrates undo into the draw-session.
See D3113
Diffstat (limited to 'source/blender/blenloader/intern/undofile.c')
-rw-r--r-- | source/blender/blenloader/intern/undofile.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/source/blender/blenloader/intern/undofile.c b/source/blender/blenloader/intern/undofile.c index ffc7d7c83f5..287936e276e 100644 --- a/source/blender/blenloader/intern/undofile.c +++ b/source/blender/blenloader/intern/undofile.c @@ -34,6 +34,15 @@ #include <string.h> #include <stdio.h> #include <math.h> +#include <fcntl.h> +#include <errno.h> + +/* open/close */ +#ifndef _WIN32 +# include <unistd.h> +#else +# include <io.h> +#endif #include "MEM_guardedalloc.h" @@ -42,6 +51,9 @@ #include "BLI_blenlib.h" #include "BLO_undofile.h" +#include "BLO_readfile.h" + +#include "BKE_main.h" /* keep last */ #include "BLI_strict_flags.h" @@ -124,3 +136,69 @@ void memfile_chunk_add(MemFile *compare, MemFile *current, const char *buf, unsi current->size += size; } } + +struct Main *BLO_memfile_main_get(struct MemFile *memfile, struct Main *oldmain, struct Scene **r_scene) +{ + struct Main *bmain_undo = NULL; + BlendFileData *bfd = BLO_read_from_memfile(oldmain, oldmain->name, memfile, NULL, BLO_READ_SKIP_NONE); + + if (bfd) { + bmain_undo = bfd->main; + if (r_scene) { + *r_scene = bfd->curscene; + } + + MEM_freeN(bfd); + } + + return bmain_undo; +} + + +/** + * Saves .blend using undo buffer. + * + * \return success. + */ +bool BLO_memfile_write_file(struct MemFile *memfile, const char *filename) +{ + MemFileChunk *chunk; + int file, oflags; + + /* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK, + * however if this is ever executed explicitly by the user, we may want to allow writing to symlinks. + */ + + 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(filename, oflags, 0666); + + if (file == -1) { + fprintf(stderr, "Unable to save '%s': %s\n", + filename, errno ? strerror(errno) : "Unknown error opening file"); + return false; + } + + for (chunk = memfile->chunks.first; chunk; chunk = chunk->next) { + if (write(file, chunk->buf, chunk->size) != chunk->size) { + break; + } + } + + close(file); + + if (chunk) { + fprintf(stderr, "Unable to save '%s': %s\n", + filename, errno ? strerror(errno) : "Unknown error writing file"); + return false; + } + return true; +} |