[poppler] 2 commits - goo/gfile.cc goo/gfile.h poppler/ErrorCodes.h poppler/PDFDoc.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Dec 11 23:27:11 UTC 2017


 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 <Thomas.Freitag at alfa.de>
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 <adamreichold at myopera.com>
 // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2013 Peter Breitenlohner <peb at mppmu.mpg.de>
-// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2013, 2017 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2017 Christoph Cullmann <cullmann at kde.org>
 //
 // 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 <cristeab at gmail.com>
 // Copyright (C) 2014 Peter Breitenlohner <peb at mppmu.mpg.de>
 // Copyright (C) 2017 Christoph Cullmann <cullmann at kde.org>
+// Copyright (C) 2017 Thomas Freitag <Thomas.Freitag at alfa.de>
 //
 // 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 <aacid at kde.org>
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 <krh at redhat.com>
 // Copyright (C) 2008 Adam Batkin <adam at batkin.net>
 // Copyright (C) 2008, 2010, 2012, 2013 Hib Eris <hib at hiberis.nl>
-// Copyright (C) 2009, 2012, 2014 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2009, 2012, 2014, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2009 Kovid Goyal <kovid at kovidgoyal.net>
 // Copyright (C) 2013 Adam Reichold <adamreichold at myopera.com>
 // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson at redneon.com>
@@ -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 <krh at redhat.com>
-// Copyright (C) 2009, 2011, 2012 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2009, 2011, 2012, 2017 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2009 Kovid Goyal <kovid at kovidgoyal.net>
 // Copyright (C) 2013 Adam Reichold <adamreichold at myopera.com>
 // Copyright (C) 2013, 2017 Adrian Johnson <ajohnson at redneon.com>
@@ -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 <aacid at kde.org>
+//
+// 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();


More information about the poppler mailing list