goo/gfile.cc | 32 ++++++++++++++++++++++++++++++-- goo/gfile.h | 14 +++++++++++--- poppler/ErrorCodes.h | 16 ++++++++++++++++ poppler/PDFDoc.cc | 11 +++++++++++ 4 files changed, 68 insertions(+), 5 deletions(-)
New commits: commit 3263fa4439e1a09dae6a0332a90b983d25bc218d Author: Thomas Freitag <[email protected]> Date: Tue Dec 12 00:26:37 2017 +0100 windows version for Error out on save if file has changed since we opened it diff --git a/goo/gfile.cc b/goo/gfile.cc index f7a4a9b7..8659440d 100644 --- a/goo/gfile.cc +++ b/goo/gfile.cc @@ -24,7 +24,7 @@ // Copyright (C) 2013 Adam Reichold <[email protected]> // Copyright (C) 2013, 2017 Adrian Johnson <[email protected]> // Copyright (C) 2013 Peter Breitenlohner <[email protected]> -// Copyright (C) 2013 Thomas Freitag <[email protected]> +// Copyright (C) 2013, 2017 Thomas Freitag <[email protected]> // Copyright (C) 2017 Christoph Cullmann <[email protected]> // // To see a description of the changes please see the Changelog file that @@ -599,6 +599,10 @@ Goffset GoffsetMax() { #ifdef _WIN32 +GooFile::GooFile(HANDLE handleA) : handle(handleA) { + GetFileTime(handleA, NULL, NULL, &modifiedTimeOnOpen); +} + int GooFile::read(char *buf, int n, Goffset offset) const { DWORD m; @@ -642,6 +646,14 @@ GooFile* GooFile::open(const wchar_t *fileName) { return handle == INVALID_HANDLE_VALUE ? NULL : new GooFile(handle); } +bool GooFile::modificationTimeChangedSinceOpen() const +{ + struct _FILETIME lastModified; + GetFileTime(handle, NULL, NULL, &lastModified); + + return modifiedTimeOnOpen.dwHighDateTime != lastModified.dwHighDateTime || modifiedTimeOnOpen.dwLowDateTime != lastModified.dwLowDateTime; +} + #else int GooFile::read(char *buf, int n, Goffset offset) const { diff --git a/goo/gfile.h b/goo/gfile.h index 6bbcb90c..13dfa3a0 100644 --- a/goo/gfile.h +++ b/goo/gfile.h @@ -23,6 +23,7 @@ // Copyright (C) 2014 Bogdan Cristea <[email protected]> // Copyright (C) 2014 Peter Breitenlohner <[email protected]> // Copyright (C) 2017 Christoph Cullmann <[email protected]> +// Copyright (C) 2017 Thomas Freitag <[email protected]> // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -147,11 +148,12 @@ public: ~GooFile() { CloseHandle(handle); } // Asuming than on windows you can't change files that are already open - bool modificationTimeChangedSinceOpen() const { return false; }; + bool modificationTimeChangedSinceOpen() const; private: - GooFile(HANDLE handleA): handle(handleA) {} + GooFile(HANDLE handleA); HANDLE handle; + struct _FILETIME modifiedTimeOnOpen; #else ~GooFile() { close(fd); } commit e4ee1392136188fab0005a0bd7b30c6d9a16d97d Author: Albert Astals Cid <[email protected]> Date: Tue Dec 12 00:24:31 2017 +0100 Error out on save if file has changed since we opened it In poppler we keep the fd of the file open so the XRef+FileStream can locate objects. This is good since we save lots of memory for not having everything on memory all the time, but that means that when we want to save we need the file to be exactly the same as it was when we created the XRef otherwise we're going to be reading from the wrong part of the "new" file. Bug #103793 diff --git a/goo/gfile.cc b/goo/gfile.cc index fe05de67..f7a4a9b7 100644 --- a/goo/gfile.cc +++ b/goo/gfile.cc @@ -19,7 +19,7 @@ // Copyright (C) 2006 Kristian Høgsberg <[email protected]> // Copyright (C) 2008 Adam Batkin <[email protected]> // Copyright (C) 2008, 2010, 2012, 2013 Hib Eris <[email protected]> -// Copyright (C) 2009, 2012, 2014 Albert Astals Cid <[email protected]> +// Copyright (C) 2009, 2012, 2014, 2017 Albert Astals Cid <[email protected]> // Copyright (C) 2009 Kovid Goyal <[email protected]> // Copyright (C) 2013 Adam Reichold <[email protected]> // Copyright (C) 2013, 2017 Adrian Johnson <[email protected]> @@ -670,6 +670,22 @@ GooFile* GooFile::open(const GooString *fileName) { return fd < 0 ? NULL : new GooFile(fd); } +GooFile::GooFile(int fdA) + : fd(fdA) +{ + struct stat statbuf; + fstat(fd, &statbuf); + modifiedTimeOnOpen = statbuf.st_mtim; +} + +bool GooFile::modificationTimeChangedSinceOpen() const +{ + struct stat statbuf; + fstat(fd, &statbuf); + + return modifiedTimeOnOpen.tv_sec != statbuf.st_mtim.tv_sec || modifiedTimeOnOpen.tv_nsec != statbuf.st_mtim.tv_nsec; +} + #endif // _WIN32 //------------------------------------------------------------------------ diff --git a/goo/gfile.h b/goo/gfile.h index 805e5232..6bbcb90c 100644 --- a/goo/gfile.h +++ b/goo/gfile.h @@ -16,7 +16,7 @@ // under GPL version 2 or later // // Copyright (C) 2006 Kristian Høgsberg <[email protected]> -// Copyright (C) 2009, 2011, 2012 Albert Astals Cid <[email protected]> +// Copyright (C) 2009, 2011, 2012, 2017 Albert Astals Cid <[email protected]> // Copyright (C) 2009 Kovid Goyal <[email protected]> // Copyright (C) 2013 Adam Reichold <[email protected]> // Copyright (C) 2013, 2017 Adrian Johnson <[email protected]> @@ -145,16 +145,22 @@ public: static GooFile *open(const wchar_t *fileName); ~GooFile() { CloseHandle(handle); } + + // Asuming than on windows you can't change files that are already open + bool modificationTimeChangedSinceOpen() const { return false; }; private: GooFile(HANDLE handleA): handle(handleA) {} HANDLE handle; #else ~GooFile() { close(fd); } + + bool modificationTimeChangedSinceOpen() const; private: - GooFile(int fdA) : fd(fdA) {} + GooFile(int fdA); int fd; + struct timespec modifiedTimeOnOpen; #endif // _WIN32 }; diff --git a/poppler/ErrorCodes.h b/poppler/ErrorCodes.h index b28528df..15b172a7 100644 --- a/poppler/ErrorCodes.h +++ b/poppler/ErrorCodes.h @@ -6,6 +6,20 @@ // //======================================================================== +//======================================================================== +// +// Modified under the Poppler project - http://poppler.freedesktop.org +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2017 Albert Astals Cid <[email protected]> +// +// To see a description of the changes please see the Changelog file that +// came with your tarball or type make ChangeLog if you are building from git +// +//======================================================================== + #ifndef ERRORCODES_H #define ERRORCODES_H @@ -33,4 +47,6 @@ #define errFileIO 10 // file I/O error +#define errFileChangedSinceOpen 11 // file has changed since opening and save can't be done + #endif diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 90f039d8..cdf96ab9 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -730,6 +730,11 @@ int PDFDoc::savePageAs(GooString *name, int pageNo) FILE *f; OutStream *outStr; XRef *yRef, *countRef; + + if (file && file->modificationTimeChangedSinceOpen()) + return errFileChangedSinceOpen; + + int rootNum = getXRef()->getNumObjects() + 1; // Make sure that special flags are set, because we are going to read @@ -901,6 +906,9 @@ int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) { } int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) { + if (file && file->modificationTimeChangedSinceOpen()) + return errFileChangedSinceOpen; + if (!xref->isModified() && mode == writeStandard) { // simply copy the original file saveWithoutChangesAs (outStr); @@ -934,6 +942,9 @@ int PDFDoc::saveWithoutChangesAs(GooString *name) { int PDFDoc::saveWithoutChangesAs(OutStream *outStr) { int c; + + if (file && file->modificationTimeChangedSinceOpen()) + return errFileChangedSinceOpen; BaseStream *copyStr = str->copy(); copyStr->reset();
_______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
