gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 61fbd358: Library (pdf.h): using execl instead


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 61fbd358: Library (pdf.h): using execl instead of system to avoid shell
Date: Fri, 17 May 2024 06:43:21 -0400 (EDT)

branch: master
commit 61fbd358a63315b9999aa017d077a87c39aeffd6
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (pdf.h): using execl instead of system to avoid shell
    
    Until now, when running Ghostscript to generate the PDF output of
    ConvertType, we would use the 'system()' function of C. However, because
    'system()' is generic, it uses the default '/bin/sh' shell to execute the
    given command. This can cause problems when '/bin/sh' is not executable
    (for example it has linking problems in the running environment).
    
    With this commit, we are using the lower-level 'execl()' function of C to
    avoid the shell overall, and directly pass our command to the system.
    
    This was fixed as part of bug #65681, but it is not yet the full fix
    because there are more 'system()' calls within Gnuastro that need to be
    fixed.
    
    This bug was reported by Sepideh Eskandarlou.
---
 configure.ac |  5 ++++-
 lib/pdf.c    | 31 +++++++++++++++++++------------
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index 31a6aa3f..49b4bad2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -736,7 +736,10 @@ AS_IF([test "x$has_ghostscript" = "xyes"],
       [AC_MSG_CHECKING(Ghostscript version)
        gsversion=$(gs --version)
        AX_COMPARE_VERSION([9.10], [gt], [$gsversion], [has_ghostscript=no])
-       AC_MSG_RESULT( $gsversion )])
+       AC_MSG_RESULT( $gsversion )
+       AC_DEFINE_UNQUOTED([PATH_GHOSTSCRIPT], ["$(which gs)"],
+                          [Location of the host system's Ghostscript binary])
+       ])
 # Note: 'has_ghostscript' can be set to 'no' within the AS_IF above, so
 # 'anywarnings' cannot be an [RUN-IF-FALSE] argument to the AS_IF above.
 AS_IF([test "x$has_ghostscript" = "xno"], [anywarnings=yes])
diff --git a/lib/pdf.c b/lib/pdf.c
index 84698f83..7b0d2558 100644
--- a/lib/pdf.c
+++ b/lib/pdf.c
@@ -104,7 +104,7 @@ gal_pdf_write(gal_data_t *in, char *filename, float 
widthincm,
               int dontoptimize, gal_data_t *marks)
 {
   size_t w_h_in_pt[2];
-  char *command, *device;
+  char *device, *devwp, *devhp, *devopt;
   char *epsname=gal_checkset_malloc_cat(filename, ".ps");
 
   /* Write the EPS file. */
@@ -118,22 +118,27 @@ gal_pdf_write(gal_data_t *in, char *filename, float 
widthincm,
   if(gal_jpeg_name_is_jpeg(filename)) device="jpeg";
   else                                device="pdfwrite";
 
-  /* Write the ghostscript command to compile the EPS file to PDF. */
-  if( asprintf(&command, "gs -q -o %s -sDEVICE=%s "
-               "-dDEVICEWIDTHPOINTS=%zu -dDEVICEHEIGHTPOINTS=%zu "
-               "-dPDFFitPage %s", filename, device,
-               w_h_in_pt[0]+2*borderwidth, w_h_in_pt[1]+2*borderwidth,
-               epsname)<0 )
+  /* Build the necessary strings. */
+  if( asprintf(&devwp, "-dDEVICEWIDTHPOINTS=%zu",
+               w_h_in_pt[0]+2*borderwidth)<0 )
+    error(EXIT_FAILURE, 0, "%s: asprintf allocation error", __func__);
+  if( asprintf(&devhp, "-dDEVICEHEIGHTPOINTS=%zu",
+               w_h_in_pt[1]+2*borderwidth)<0 )
+    error(EXIT_FAILURE, 0, "%s: asprintf allocation error", __func__);
+  if( asprintf(&devopt, "-sDEVICE=%s", device)<0 )
     error(EXIT_FAILURE, 0, "%s: asprintf allocation error", __func__);
 
-  /* Run Ghostscript. */
-  if(system(command))
+  /* Run Ghostscript (if the command changes, also change the command in
+     the error message). */
+  if( execl(PATH_GHOSTSCRIPT, "gs", "-q", "-o", filename, devopt,
+            devwp, devhp, "-dPDFFitPage", epsname, (char *)0) )
     error(EXIT_FAILURE, 0, "the Ghostscript command (printed after "
           "this message) to convert the EPS file to PDF was not "
           "successful! The EPS file ('%s') is left if you want to "
           "convert it through any other means (for example the "
-          "'epspdf' program). The Ghostscript command was: %s",
-          epsname, command);
+          "'epspdf' program). The Ghostscript command was: %s "
+          "-q -o %s %s %s %s -dPDFFitPage %s", PATH_GHOSTSCRIPT,
+          epsname, filename, devopt, devwp, devhp, epsname);
 
   /* Delete the EPS file. */
   errno=0;
@@ -141,6 +146,8 @@ gal_pdf_write(gal_data_t *in, char *filename, float 
widthincm,
     error(EXIT_FAILURE, errno, "%s", epsname);
 
   /* Clean up. */
-  free(command);
+  free(devhp);
+  free(devwp);
+  free(devopt);
   free(epsname);
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]