[poppler] 3 commits - fofi/FoFiBase.cc fofi/FoFiIdentifier.cc glib/poppler-attachment.cc glib/poppler-media.cc goo/gfile.cc goo/gfile.h poppler/CairoFontEngine.cc poppler/FileSpec.cc poppler/GfxState.cc poppler/GlobalParams.cc poppler/GlobalParamsWin.cc poppler/PDFDoc.cc poppler/PSOutputDev.cc poppler/TextOutputDev.cc splash/SplashBitmap.cc

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Jan 5 16:26:11 UTC 2019


 fofi/FoFiBase.cc           |    3 +-
 fofi/FoFiIdentifier.cc     |    3 +-
 glib/poppler-attachment.cc |    5 ++--
 glib/poppler-media.cc      |    5 ++--
 goo/gfile.cc               |   51 +++++++++++++++++++++++++++++++++++++++++++--
 goo/gfile.h                |    3 ++
 poppler/CairoFontEngine.cc |    2 -
 poppler/FileSpec.cc        |    3 +-
 poppler/GfxState.cc        |    5 ++--
 poppler/GlobalParams.cc    |    4 +--
 poppler/GlobalParamsWin.cc |    2 -
 poppler/PDFDoc.cc          |    6 ++---
 poppler/PSOutputDev.cc     |    4 +--
 poppler/TextOutputDev.cc   |    3 +-
 splash/SplashBitmap.cc     |    7 +++---
 15 files changed, 82 insertions(+), 24 deletions(-)

New commits:
commit d5625de8ce3fc31608248fe14b12c4c7d1a43593
Author: Christian Persch <chpe at src.gnome.org>
Date:   Thu Jan 3 21:11:49 2019 +0100

    gfile: Open files with CLOEXEC flag set
    
    First try to atomically open the file using O_CLOEXEC for open()
    and the "e" mode for fopen(), and if that doesn't work or O_CLOEXEC
    isn't defined, fall back to opening the file first and applying
    the FD_CLOEXEC flag afterwards.

diff --git a/goo/gfile.cc b/goo/gfile.cc
index c2973416..c33b580a 100644
--- a/goo/gfile.cc
+++ b/goo/gfile.cc
@@ -66,6 +66,8 @@
 
 #ifndef _WIN32
 
+using namespace std::string_literals;
+
 namespace {
 
 template< typename... >
@@ -270,8 +272,33 @@ GooString *appendToPath(GooString *path, const char *fileName) {
 #endif
 }
 
+static bool makeFileDescriptorCloexec(int fd) {
+#ifdef FD_CLOEXEC
+  int flags = fcntl(fd, F_GETFD);
+  if (flags >= 0 && !(flags & FD_CLOEXEC))
+    flags = fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+
+  return flags >= 0;
+#else
+  return true;
+#endif
+}
+
 int openFileDescriptor(const char *path, int flags) {
-  return open(path, flags);
+#ifdef O_CLOEXEC
+  return open(path, flags | O_CLOEXEC);
+#else
+  int fd = open(path, flags);
+  if (fd == -1)
+    return fd;
+
+  if (!makeFileDescriptorCloexec(fd)) {
+    close(fd);
+    return -1;
+  }
+
+  return fd;
+#endif
 }
 
 FILE *openFile(const char *path, const char *mode) {
@@ -333,7 +360,23 @@ FILE *openFile(const char *path, const char *mode) {
     return fopen(nPath, mode);
   }
 #else
-  return fopen(path, mode);
+  // First try to atomically open the file with CLOEXEC
+  const std::string modeStr = mode + "e"s;
+  FILE *file = fopen(path, modeStr.c_str());
+  if (file != nullptr)
+    return file;
+
+  // Fall back to the provided mode and apply CLOEXEC afterwards
+  file = fopen(path, mode);
+  if (file == nullptr)
+    return nullptr;
+
+  if (!makeFileDescriptorCloexec(fileno(file))) {
+    fclose(file);
+    return nullptr;
+  }
+
+  return file;
 #endif
 }
 
commit 4a3eef323d72b06780c318f58917f884eecc812e
Author: Christian Persch <chpe at src.gnome.org>
Date:   Thu Jan 3 21:11:49 2019 +0100

    gfile: Add wrapper for open(3p) and use it instead of directly calling open
    
    This is in preparation to making the wrapper enforce the O_CLOEXEC flag.

diff --git a/goo/gfile.cc b/goo/gfile.cc
index 819559c0..c2973416 100644
--- a/goo/gfile.cc
+++ b/goo/gfile.cc
@@ -270,6 +270,10 @@ GooString *appendToPath(GooString *path, const char *fileName) {
 #endif
 }
 
+int openFileDescriptor(const char *path, int flags) {
+  return open(path, flags);
+}
+
 FILE *openFile(const char *path, const char *mode) {
 #ifdef _WIN32
   OSVERSIONINFO version;
@@ -485,7 +489,7 @@ GooFile* GooFile::open(const GooString *fileName) {
 #ifdef VMS
   int fd = ::open(fileName->c_str(), Q_RDONLY, "ctx=stm");
 #else
-  int fd = ::open(fileName->c_str(), O_RDONLY);
+  int fd = openFileDescriptor(fileName->c_str(), O_RDONLY);
 #endif
   
   return fd < 0 ? nullptr : new GooFile(fd);
diff --git a/goo/gfile.h b/goo/gfile.h
index bd58e6c0..b0b942fd 100644
--- a/goo/gfile.h
+++ b/goo/gfile.h
@@ -88,6 +88,9 @@ typedef long long Goffset;
 // string, denoting the current directory).  Returns <path>.
 extern GooString *appendToPath(GooString *path, const char *fileName);
 
+// Open a file descriptor
+extern int openFileDescriptor(const char *path, int flags);
+
 // Open a file.  On Windows, this converts the path from UTF-8 to
 // UCS-2 and calls _wfopen (if available).  On other OSes, this simply
 // calls fopen.
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 4876ba00..3c132550 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -280,7 +280,7 @@ _ft_new_face (FT_Library lib,
 
   if (font_data == nullptr) {
     /* if we fail to mmap the file, just pass it to FreeType instead */
-    tmpl.fd = open (filename, O_RDONLY);
+    tmpl.fd = openFileDescriptor (filename, O_RDONLY);
     if (tmpl.fd == -1)
       return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out);
 
commit e1e4457a235f6107c09d32994fc628efa9e7bd0e
Author: Christian Persch <chpe at src.gnome.org>
Date:   Thu Jan 3 21:11:49 2019 +0100

    all: Use the openFile fopen wrapper from gfile.h
    
    Use the openFile wrapper instead of calling fopen directly
    in the libraries.

diff --git a/fofi/FoFiBase.cc b/fofi/FoFiBase.cc
index ad5d0067..1337c0d0 100644
--- a/fofi/FoFiBase.cc
+++ b/fofi/FoFiBase.cc
@@ -26,6 +26,7 @@
 
 #include <stdio.h>
 #include <limits.h>
+#include "goo/gfile.h"
 #include "goo/gmem.h"
 #include "poppler/Error.h"
 #include "FoFiBase.h"
@@ -51,7 +52,7 @@ char *FoFiBase::readFile(const char *fileName, int *fileLen) {
   char *buf;
   int n;
 
-  if (!(f = fopen(fileName, "rb"))) {
+  if (!(f = openFile(fileName, "rb"))) {
     error(errIO, -1, "Cannot open '{0:s}'", fileName);
     return nullptr;
   }
diff --git a/fofi/FoFiIdentifier.cc b/fofi/FoFiIdentifier.cc
index e557e92a..e6e4ba1b 100644
--- a/fofi/FoFiIdentifier.cc
+++ b/fofi/FoFiIdentifier.cc
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <limits.h>
+#include "goo/gfile.h"
 #include "FoFiIdentifier.h"
 
 //------------------------------------------------------------------------
@@ -184,7 +185,7 @@ private:
 FileReader *FileReader::make(const char *fileName) {
   FILE *fA;
 
-  if (!(fA = fopen(fileName, "rb"))) {
+  if (!(fA = openFile(fileName, "rb"))) {
     return nullptr;
   }
   return new FileReader(fA);
diff --git a/glib/poppler-attachment.cc b/glib/poppler-attachment.cc
index dd7064bf..ff09edcf 100644
--- a/glib/poppler-attachment.cc
+++ b/glib/poppler-attachment.cc
@@ -18,7 +18,8 @@
 
 #include "config.h"
 #include <errno.h>
-#include <glib/gstdio.h>
+
+#include <goo/gfile.h>
 
 #include "poppler.h"
 #include "poppler-private.h"
@@ -173,7 +174,7 @@ poppler_attachment_save (PopplerAttachment  *attachment,
   
   g_return_val_if_fail (POPPLER_IS_ATTACHMENT (attachment), FALSE);
 
-  f = g_fopen (filename, "wb");
+  f = openFile (filename, "wb");
 
   if (f == nullptr)
     {
diff --git a/glib/poppler-media.cc b/glib/poppler-media.cc
index ab5f4c0e..23689ae4 100644
--- a/glib/poppler-media.cc
+++ b/glib/poppler-media.cc
@@ -20,7 +20,8 @@
 #include "config.h"
 
 #include <errno.h>
-#include <glib/gstdio.h>
+
+#include <goo/gfile.h>
 
 #include "poppler-media.h"
 #include "poppler-private.h"
@@ -214,7 +215,7 @@ poppler_media_save (PopplerMedia *poppler_media,
   g_return_val_if_fail (POPPLER_IS_MEDIA (poppler_media), FALSE);
   g_return_val_if_fail (poppler_media->stream.isStream(), FALSE);
 
-  f = g_fopen (filename, "wb");
+  f = openFile (filename, "wb");
 
   if (f == nullptr)
     {
diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc
index 7c12da63..63452e6e 100644
--- a/poppler/FileSpec.cc
+++ b/poppler/FileSpec.cc
@@ -28,6 +28,7 @@
 #include <config.h>
 
 #include "FileSpec.h"
+#include "goo/gfile.h"
 
 EmbFile::EmbFile(Object &&efStream)
 {
@@ -83,7 +84,7 @@ bool EmbFile::save(const char *path) {
   FILE *f;
   bool ret;
 
-  if (!(f = fopen(path, "wb"))) {
+  if (!(f = openFile(path, "wb"))) {
     return false;
   }
   ret = save2(f);
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index c5a10000..14c7d47d 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -46,6 +46,7 @@
 #include <stddef.h>
 #include <math.h>
 #include <string.h>
+#include "goo/gfile.h"
 #include "goo/gmem.h"
 #include "Error.h"
 #include "Object.h"
@@ -461,7 +462,7 @@ cmsHPROFILE loadColorProfile(const char *fileName)
   if (fileName[0] == '/') {
     // full path
     // check if open the file
-    if ((fp = fopen(fileName,"r")) != nullptr) {
+    if ((fp = openFile(fileName,"r")) != nullptr) {
       fclose(fp);
       hp = cmsOpenProfileFromFile(fileName,"r");
     }
@@ -471,7 +472,7 @@ cmsHPROFILE loadColorProfile(const char *fileName)
   GooString *path = new GooString(GLOBAL_COLOR_PROFILE_DIR);
   path->append(fileName);
   // check if open the file
-  if ((fp = fopen(path->c_str(),"r")) != nullptr) {
+  if ((fp = openFile(path->c_str(),"r")) != nullptr) {
     fclose(fp);
     hp = cmsOpenProfileFromFile(path->c_str(),"r");
   }
diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index 9a670ce3..9ca0a428 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -1064,7 +1064,7 @@ void GlobalParams::setupBaseFonts(char *dir) {
     fileName = nullptr;
     if (dir) {
       fileName = appendToPath(new GooString(dir), displayFontTab[i].t1FileName);
-      if ((f = fopen(fileName->c_str(), "rb"))) {
+      if ((f = openFile(fileName->c_str(), "rb"))) {
 	      fclose(f);
       } else {
 	      delete fileName;
@@ -1074,7 +1074,7 @@ void GlobalParams::setupBaseFonts(char *dir) {
     for (j = 0; !fileName && displayFontDirs[j]; ++j) {
       fileName = appendToPath(new GooString(displayFontDirs[j]),
 			      displayFontTab[i].t1FileName);
-      if ((f = fopen(fileName->c_str(), "rb"))) {
+      if ((f = openFile(fileName->c_str(), "rb"))) {
 	      fclose(f);
       } else {
 	      delete fileName;
diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc
index 83ece3c5..86a28f41 100644
--- a/poppler/GlobalParamsWin.cc
+++ b/poppler/GlobalParamsWin.cc
@@ -216,7 +216,7 @@ static void GetWindowsFontDir(char *winFontDir, int cbWinFontDirLen)
 
 static bool FileExists(const char *path)
 {
-    FILE * f = fopen(path, "rb");
+    FILE * f = openFile(path, "rb");
     if (f) {
         fclose(f);
         return true;
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 93fa4464..12f29191 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -897,7 +897,7 @@ int PDFDoc::savePageAs(GooString *name, int pageNo)
   Ref *refPage = getCatalog()->getPageRef(pageNo);
   Object page = getXRef()->fetch(refPage->num, refPage->gen);
 
-  if (!(f = fopen(name->c_str(), "wb"))) {
+  if (!(f = openFile(name->c_str(), "wb"))) {
     error(errIO, -1, "Couldn't open file '{0:t}'", name);
     return errOpenFile;
   }
@@ -1030,7 +1030,7 @@ int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) {
   OutStream *outStr;
   int res;
 
-  if (!(f = fopen(name->c_str(), "wb"))) {
+  if (!(f = openFile(name->c_str(), "wb"))) {
     error(errIO, -1, "Couldn't open file '{0:t}'", name);
     return errOpenFile;
   }
@@ -1062,7 +1062,7 @@ int PDFDoc::saveWithoutChangesAs(GooString *name) {
   OutStream *outStr;
   int res;
 
-  if (!(f = fopen(name->c_str(), "wb"))) {
+  if (!(f = openFile(name->c_str(), "wb"))) {
     error(errIO, -1, "Couldn't open file '{0:t}'", name);
     return errOpenFile;
   }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 1eb75aec..6294f7ec 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1141,7 +1141,7 @@ PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc,
 #endif
   } else {
     fileTypeA = psFile;
-    if (!(f = fopen(fileName, "w"))) {
+    if (!(f = openFile(fileName, "w"))) {
       error(errIO, -1, "Couldn't open PostScript file '{0:s}'", fileName);
       ok = false;
       return;
@@ -2309,7 +2309,7 @@ void PSOutputDev::setupExternalType1Font(GooString *fileName, GooString *psName)
   embFontList->append("\n");
 
   // copy the font file
-  if (!(fontFile = fopen(fileName->c_str(), "rb"))) {
+  if (!(fontFile = openFile(fileName->c_str(), "rb"))) {
     error(errIO, -1, "Couldn't open external font file");
     return;
   }
diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
index 7a8f180c..f1ec40db 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -59,6 +59,7 @@
 #include <fcntl.h> // for O_BINARY
 #include <io.h>    // for setmode
 #endif
+#include "goo/gfile.h"
 #include "goo/gmem.h"
 #include "goo/GooString.h"
 #include "goo/GooList.h"
@@ -5637,7 +5638,7 @@ TextOutputDev::TextOutputDev(const char *fileName, bool physLayoutA,
       // keep DOS from munging the end-of-line characters
       setmode(fileno(stdout), O_BINARY);
 #endif
-    } else if ((outputStream = fopen(fileName, append ? "ab" : "wb"))) {
+    } else if ((outputStream = openFile(fileName, append ? "ab" : "wb"))) {
       needClose = true;
     } else {
       error(errIO, -1, "Couldn't open text file '{0:s}'", fileName);
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 856fa084..7ce8b6f9 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <limits.h>
+#include "goo/gfile.h"
 #include "goo/gmem.h"
 #include "SplashErrorCodes.h"
 #include "SplashBitmap.h"
@@ -165,7 +166,7 @@ SplashError SplashBitmap::writePNMFile(char *fileName) {
   FILE *f;
   SplashError e;
 
-  if (!(f = fopen(fileName, "wb"))) {
+  if (!(f = openFile(fileName, "wb"))) {
     return splashErrOpenFile;
   }
 
@@ -262,7 +263,7 @@ SplashError SplashBitmap::writeAlphaPGMFile(char *fileName) {
   if (!alpha) {
     return splashErrModeMismatch;
   }
-  if (!(f = fopen(fileName, "wb"))) {
+  if (!(f = openFile(fileName, "wb"))) {
     return splashErrOpenFile;
   }
   fprintf(f, "P5\n%d %d\n255\n", width, height);
@@ -338,7 +339,7 @@ SplashError SplashBitmap::writeImgFile(SplashImageFileFormat format, const char
   FILE *f;
   SplashError e;
 
-  if (!(f = fopen(fileName, "wb"))) {
+  if (!(f = openFile(fileName, "wb"))) {
     return splashErrOpenFile;
   }
 


More information about the poppler mailing list