diff options
author | Paul Gardiner <paulg.artifex@glidos.net> | 2012-11-26 16:36:18 +0000 |
---|---|---|
committer | Paul Gardiner <paulg.artifex@glidos.net> | 2012-11-27 10:40:23 +0000 |
commit | 4c2e89d670317b898ece971c7b4d111e473c9575 (patch) | |
tree | 64be7ca7253eab543e910d61c433282e5399de7d /apps/pdfapp.c | |
parent | eaaf501fa47616691ab10b151022b4c91cc210b4 (diff) | |
download | mupdf-4c2e89d670317b898ece971c7b4d111e473c9575.tar.xz |
Forms: avoid directly saving to the original file
MuPDF needs access to the original file when saving, and in any case
directly overwritting the original file has much more potential for
data loss than use of a temporary file.
Diffstat (limited to 'apps/pdfapp.c')
-rw-r--r-- | apps/pdfapp.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/apps/pdfapp.c b/apps/pdfapp.c index 598b40b5..9760385b 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -187,6 +187,7 @@ void pdfapp_open(pdfapp_t *app, char *filename, int reload) } } + app->docpath = fz_strdup(ctx, filename); app->doctitle = filename; if (strrchr(app->doctitle, '\\')) app->doctitle = strrchr(app->doctitle, '\\') + 1; @@ -248,6 +249,10 @@ void pdfapp_close(pdfapp_t *app) fz_free(app->ctx, app->doctitle); app->doctitle = NULL; + if (app->docpath) + fz_free(app->ctx, app->docpath); + app->docpath = NULL; + if (app->image) fz_drop_pixmap(app->ctx, app->image); app->image = NULL; @@ -277,6 +282,32 @@ void pdfapp_close(pdfapp_t *app) fz_flush_warnings(app->ctx); } +static int gen_tmp_file(char *buf, int len) +{ + int i; + char *name = strrchr(buf, '/'); + + if (name == NULL) + name = strrchr(buf, '\\'); + + if (name != NULL) + name++; + else + name = buf; + + for (i = 0; i < 10000; i++) + { + FILE *f; + snprintf(name, buf+len-name, "tmp%04d", i); + f = fopen(buf, "r"); + if (f == NULL) + return 1; + fclose(f); + } + + return 0; +} + static int pdfapp_save(pdfapp_t *app) { char buf[PATH_MAX]; @@ -290,7 +321,44 @@ static int pdfapp_save(pdfapp_t *app) opts.do_garbage = 1; opts.do_linear = 0; - fz_write_document(app->doc, buf, &opts); + if (strcmp(buf, app->docpath) == 0) + { + if (gen_tmp_file(buf, PATH_MAX)) + { + int written; + + fz_var(written); + fz_try(app->ctx) + { + fz_write_document(app->doc, buf, &opts); + written = 1; + } + fz_catch(app->ctx) + { + written = 0; + } + + if (written) + { + char buf2[PATH_MAX]; + strncpy(buf2, app->docpath, PATH_MAX); + pdfapp_close(app); + winreplacefile(buf, buf2); + pdfapp_open(app, buf2, 1); + } + + return written; + } + else + { + return 0; + } + } + else + { + fz_write_document(app->doc, buf, &opts); + return 1; + } return 1; } |