about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-12-29 20:46:34 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-12-29 20:46:34 +0000
commitd87a19306b69fa7e537b265983b54071805a5eb5 (patch)
tree9b0ab24c42650f8cc9cda9edf090a0bcc3e9daf6
parentfdcaa9b6cc10ca54d02b4d1aae57bb60ddc9e316 (diff)
downloadnetpbm-mirror-d87a19306b69fa7e537b265983b54071805a5eb5.tar.gz
netpbm-mirror-d87a19306b69fa7e537b265983b54071805a5eb5.tar.xz
netpbm-mirror-d87a19306b69fa7e537b265983b54071805a5eb5.zip
Release 10.35.72
git-svn-id: http://svn.code.sf.net/p/netpbm/code/super_stable@1077 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/ppm/xpmtoppm.c5
-rw-r--r--doc/HISTORY10
-rw-r--r--lib/libpamread.c9
-rw-r--r--lib/libsystem.c147
4 files changed, 143 insertions, 28 deletions
diff --git a/converter/ppm/xpmtoppm.c b/converter/ppm/xpmtoppm.c
index 9dddfd83..96996c6b 100644
--- a/converter/ppm/xpmtoppm.c
+++ b/converter/ppm/xpmtoppm.c
@@ -161,7 +161,7 @@ static unsigned int
 getNumber(char * const p, unsigned int const size) {
 
     unsigned int retval;
-    char * q;
+    unsigned char * q;
     
     retval = 0;
     for (q = p; q < p+size; ++q)
@@ -465,7 +465,8 @@ readXpm1Header(FILE * const stream, int * const widthP, int * const heightP,
     char line[MAX_LINE+1], str1[MAX_LINE+1], str2[MAX_LINE+1];
     char *t1;
     char *t2;
-    int format, v;
+    int format;
+    unsigned int v;
     int i, j;
     bool processedStaticChar;  
         /* We have read up to and interpreted the "static char..." line */
diff --git a/doc/HISTORY b/doc/HISTORY
index c99e1afd..7f6dc1fd 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,6 +4,16 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
+09.12.29 BJH  Release 10.35.72
+
+              libnetpbm: When reading plain format PNM with PAM routines,
+              validate pixel against maxval (necessary for integer non-overrun
+              guarantees).
+
+              xpmtoppm: fix wild pointer with color index > 127.
+
+              pm_system*: fix various bugs.
+
 09.12.10 BJH  Release 10.35.71
 
               pamtosvg: fix compile failure from 10.35.70
diff --git a/lib/libpamread.c b/lib/libpamread.c
index 1b65745a..3d4b6448 100644
--- a/lib/libpamread.c
+++ b/lib/libpamread.c
@@ -55,9 +55,14 @@ readPlainNonPbmRow(const struct pam * const pamP,
     for (col = 0; col < pamP->width; ++col) {
         unsigned int plane;
         for (plane = 0; plane < pamP->depth; ++plane)
-            if (tuplerow)
+            if (tuplerow) {
                 tuplerow[col][plane] = pm_getuint(pamP->file);
-            else
+
+                if (tuplerow[col][plane] > pamP->maxval)
+                    pm_error("Plane %u sample value %lu exceeds the "
+                             "image maxval of %lu",
+                             plane, tuplerow[col][plane], pamP->maxval);
+            } else
                 pm_getuint(pamP->file);  /* read data and discard */
     }
 }
diff --git a/lib/libsystem.c b/lib/libsystem.c
index 560f0a9c..094480e7 100644
--- a/lib/libsystem.c
+++ b/lib/libsystem.c
@@ -31,8 +31,8 @@
 
 static void
 execProgram(const char * const shellCommand,
-            int          const inputPipeFd,
-            int          const outputPipeFd) {
+            int          const stdinFd,
+            int          const stdoutFd) {
 /*----------------------------------------------------------------------------
    Run the shell command 'shellCommand', supplying to the shell
    'inputPipeFd' as its Standard Input and 'outputPipeFd' as its 
@@ -42,31 +42,39 @@ execProgram(const char * const shellCommand,
 -----------------------------------------------------------------------------*/
     int stdinSaveFd, stdoutSaveFd;
     int rc;
+    int execErrno;
 
     /* Make inputPipeFd Standard Input.
        Make outputPipeFd Standard Output.
     */
-    stdinSaveFd = dup(STDIN);
-    stdoutSaveFd = dup(STDOUT);
-    
-    close(STDIN);
-    close(STDOUT);
-
-    dup2(inputPipeFd, STDIN);
-    dup2(outputPipeFd, STDOUT);
+    if (stdinFd != STDIN) {
+        stdinSaveFd  = dup(STDIN);
+        close(STDIN);
+        dup2(stdinFd, STDIN);
+    }
+    if (stdoutFd != STDOUT) {
+        stdoutSaveFd = dup(STDOUT);
+        close(STDOUT);
+        dup2(stdoutFd, STDOUT);
+    }
 
     rc = execl("/bin/sh", "sh", "-c", shellCommand, NULL);
 
-    close(STDIN);
-    close(STDOUT);
-    dup2(stdinSaveFd, STDIN);
-    dup2(stdoutSaveFd, STDOUT);
-    close(stdinSaveFd);
-    close(stdoutSaveFd);
+    execErrno = errno;
 
+    if (stdinFd != STDIN) {
+        close(STDIN);
+        dup2(stdinSaveFd, STDIN);
+        close(stdinSaveFd);
+    }
+    if (stdoutFd != STDOUT) {
+        close(STDOUT);
+        dup2(stdoutSaveFd, STDOUT);
+        close(stdoutSaveFd);
+    }
     if (rc < 0)
         pm_error("Unable to exec the shell.  Errno=%d (%s)",
-                 errno, strerror(errno));
+                 execErrno, strerror(execErrno));
     else
         pm_error("INTERNAL ERROR.  execl() returns, but does not fail.");
 }
@@ -126,7 +134,7 @@ spawnProcessor(const char * const shellCommand,
 
     processorpid = fork();
     if (processorpid < 0) {
-        pm_error("fork() of processor process failed.  errno=%d (%s)\n", 
+        pm_error("fork() of processor process failed.  errno=%d (%s)", 
                  errno, strerror(errno));
     } else if (processorpid == 0) {
         /* The second child */
@@ -146,14 +154,103 @@ spawnProcessor(const char * const shellCommand,
 }
 
 
+
+static const char *
+signalName(unsigned int const signalClass) {
+
+    if (signalClass <= SIGSYS) {
+        switch (signalClass) {
+        case SIGHUP:
+            return "SIGHUP";
+        case SIGINT:
+            return "SIGINT";
+        case SIGQUIT:
+            return "SIGQUIT";
+        case SIGILL:
+            return "SIGILL";
+        case SIGTRAP:
+            return "SIGTRAP";
+        case SIGABRT:
+            return "SIGABRT";
+        case SIGBUS:
+            return "SIGBUS";
+        case SIGFPE:
+            return "SIGFPE";
+        case SIGKILL:
+            return "SIGKILL";
+        case SIGUSR1:
+            return "SIGUSR1";
+        case SIGSEGV:
+            return "SIGSEGV";
+        case SIGUSR2:
+            return "SIGUSR2";
+        case SIGPIPE:
+            return "SIGPIPE";
+        case SIGALRM:
+            return "SIGALRM";
+        case SIGTERM:
+            return "SIGTERM";
+        case SIGCHLD:
+            return "SIGCHLD";
+        case SIGCONT:
+            return "SIGCONT";
+        case SIGSTOP:
+            return "SIGSTOP";
+        case SIGTSTP:
+            return "SIGTSTP";
+        case SIGTTIN:
+            return "SIGTTIN";
+        case SIGTTOU:
+            return "SIGTTOU";
+        case SIGURG:
+            return "SIGURG";
+        case SIGXCPU:
+            return "SIGXCPU";
+        case SIGXFSZ:
+            return "SIGXFSZ";
+        case SIGVTALRM:
+            return "SIGVTALRM";
+        case SIGPROF:
+            return "SIGPROF";
+        case SIGWINCH:
+            return "SIGWINCH";
+        case SIGIO:
+            return "SIGIO";
+        case SIGPWR:
+            return "SIGPWR";
+        case SIGSYS:
+            return "SIGSYS";
+        default:
+            return "???";
+        }
+    } else if ((int)signalClass >= SIGRTMIN && (int)signalClass <= SIGRTMAX)
+        return "SIGRTxxx";
+    else
+        return "???";
+}
+
+
+
 static void
 cleanupProcessorProcess(pid_t const processorPid) {
 
-    int status;
-    waitpid(processorPid, &status, 0);
-    if (status != 0) 
-        pm_message("Shell process ended abnormally.  "
-                   "completion code = %d", status);
+    int terminationStatus;
+    waitpid(processorPid, &terminationStatus, 0);
+
+    if (WIFEXITED(terminationStatus)) {
+        int const exitStatus = WEXITSTATUS(terminationStatus);
+
+        if (exitStatus != 0)
+            pm_message("Shell process exited with abnormal exist status %u.  ",
+                       exitStatus);
+    } else if (WIFSIGNALED(terminationStatus)) {
+        pm_message("Shell process was killed by a Class %u (%s) signal.",
+                   WTERMSIG(terminationStatus),
+                   signalName(WTERMSIG(terminationStatus)));
+    } else {
+        pm_message("Shell process died, but its termination status "
+                   "0x%x  doesn't make sense", terminationStatus);
+    }
 }
 
 
@@ -204,8 +301,10 @@ pm_system(void stdinFeeder(int, void *),
    But if 'stdinFeeder' is NULL, just feed the shell our own Standard
    Input.  And if 'stdoutFeeder' is NULL, just send its Standard Output
    to our own Standard Output.
------------------------------------------------------------------------------*/
 
+   Run the program 'progName' with arguments argArray[] (terminated by NULL
+   element).  That includes arg0.
+-----------------------------------------------------------------------------*/
     /* If 'stdinFeeder' is non-NULL, we create a child process to run
        'stdinFeeder' and create a pipe between from that process as the
        shell's Standard Input.