about summary refs log tree commit diff
path: root/lib/libpam.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2016-03-27 01:38:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2016-03-27 01:38:28 +0000
commit367c9cb514c9da766488b9bdb218a18e31cb7624 (patch)
treef9e343be94161a4837f0f1c1d072a35538ae0f63 /lib/libpam.c
parent6e88e3326cb0c7f7975b56189278cab3f84ba1bd (diff)
downloadnetpbm-mirror-367c9cb514c9da766488b9bdb218a18e31cb7624.tar.gz
netpbm-mirror-367c9cb514c9da766488b9bdb218a18e31cb7624.tar.xz
netpbm-mirror-367c9cb514c9da766488b9bdb218a18e31cb7624.zip
Promote Stable (10.47) to Super Stable
git-svn-id: http://svn.code.sf.net/p/netpbm/code/super_stable@2691 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/libpam.c')
-rw-r--r--lib/libpam.c96
1 files changed, 57 insertions, 39 deletions
diff --git a/lib/libpam.c b/lib/libpam.c
index 656f5361..ab75fab6 100644
--- a/lib/libpam.c
+++ b/lib/libpam.c
@@ -5,7 +5,7 @@
    that deal with the PAM (Portable Arbitrary Format) image format.
 -----------------------------------------------------------------------------*/
 
-/* See libpm.c for the complicated explanation of this 32/64 bit file
+/* See pmfileio.c for the complicated explanation of this 32/64 bit file
    offset stuff.
 */
 #define _FILE_OFFSET_BITS 64
@@ -86,24 +86,32 @@ validateComputableSize(struct pam * const pamP) {
    Another common operation is adding 1 or 2 to the highest row, column,
    or plane number in the image, so we make sure that's possible.
 -----------------------------------------------------------------------------*/
-    unsigned int const depth = allocationDepth(pamP);
-
-    if (depth > INT_MAX/sizeof(sample))
-        pm_error("image depth (%u) too large to be processed", depth);
-    else if (pamP->width > 0 && depth * sizeof(sample) > INT_MAX/pamP->width)
-        pm_error("image width and depth (%u, %u) too large "
-                 "to be processed.", pamP->width, depth);
-    else if (pamP->width * (depth * sizeof(sample)) >
-             INT_MAX - depth * sizeof(tuple *))
-        pm_error("image width and depth (%u, %u) too large "
-                 "to be processed.", pamP->width, depth);
-    
-    if (depth > INT_MAX - 2)
-        pm_error("image depth (%u) too large to be processed", depth);
-    if (pamP->width > INT_MAX - 2)
-        pm_error("image width (%u) too large to be processed", pamP->width);
-    if (pamP->height > INT_MAX - 2)
-        pm_error("image height (%u) too large to be processed", pamP->height);
+    if (pamP->width == 0)
+        pm_error("Width is zero.  Image must be at least one pixel wide");
+    else if (pamP->height == 0)
+        pm_error("Height is zero.  Image must be at least one pixel high");
+    else {
+        unsigned int const depth = allocationDepth(pamP);
+
+        if (depth > INT_MAX/sizeof(sample))
+            pm_error("image depth (%u) too large to be processed", depth);
+        else if (depth * sizeof(sample) > INT_MAX/pamP->width)
+            pm_error("image width and depth (%u, %u) too large "
+                     "to be processed.", pamP->width, depth);
+        else if (pamP->width * (depth * sizeof(sample)) >
+                 INT_MAX - depth * sizeof(tuple *))
+            pm_error("image width and depth (%u, %u) too large "
+                     "to be processed.", pamP->width, depth);
+        
+        if (depth > INT_MAX - 2)
+            pm_error("image depth (%u) too large to be processed", depth);
+        if (pamP->width > INT_MAX - 2)
+            pm_error("image width (%u) too large to be processed",
+                     pamP->width);
+        if (pamP->height > INT_MAX - 2)
+            pm_error("image height (%u) too large to be processed",
+                     pamP->height);
+    }
 }
 
 
@@ -532,16 +540,20 @@ process_header_line(char                const buffer[],
             pamP->maxval = atoi(value);
             headerSeenP->maxval = TRUE;
         } else if (strcmp(label, "TUPLTYPE") == 0) {
-            int len = strlen(pamP->tuple_type);
-            if (len + strlen(value) + 1 > sizeof(pamP->tuple_type)-1)
-                pm_error("TUPLTYPE value too long in PAM header");
-            if (len == 0)
-                strcpy(pamP->tuple_type, value);
+            if (strlen(value) == 0)
+                pm_error("TUPLTYPE header does not have any tuple type text");
             else {
-                strcat(pamP->tuple_type, "\n");
-                strcat(pamP->tuple_type, value);
+                size_t const oldLen = strlen(pamP->tuple_type);
+                if (oldLen + strlen(value) + 1 > sizeof(pamP->tuple_type)-1)
+                    pm_error("TUPLTYPE value too long in PAM header");
+                if (oldLen == 0)
+                    strcpy(pamP->tuple_type, value);
+                else {
+                    strcat(pamP->tuple_type, " ");
+                    strcat(pamP->tuple_type, value);
+                }
+                pamP->tuple_type[sizeof(pamP->tuple_type)-1] = '\0';
             }
-            pamP->tuple_type[sizeof(pamP->tuple_type)-1] = '\0';
         } else 
             pm_error("Unrecognized header line: '%s'.  "
                      "Possible missing ENDHDR line?", label);
@@ -670,10 +682,10 @@ pnm_readpaminitrestaspnm(FILE * const fileP,
 -----------------------------------------------------------------------------*/
     struct pam pam;
 
-    pam.size        = sizeof(struct pam);
-    pam.file        = fileP;
-    pam.len         = PAM_STRUCT_SIZE(tuple_type);
-    pam.format      = PAM_FORMAT;
+    pam.size   = sizeof(struct pam);
+    pam.file   = fileP;
+    pam.len    = PAM_STRUCT_SIZE(tuple_type);
+    pam.format = PAM_FORMAT;
 
     readpaminitrest(&pam);
 
@@ -691,12 +703,11 @@ pnm_readpaminitrestaspnm(FILE * const fileP,
     case 1:
         *formatP = RPGM_FORMAT;
         break;
-    default: {
+    default:
         pm_error("Cannot treat PAM image as PPM or PGM, "
                  "because its depth (%u) "
                  "is not 1 or 3.", pam.depth);
     }
-    }
 
     *colsP   = pam.width;
     *rowsP   = pam.height;
@@ -775,7 +786,8 @@ pnm_readpaminit(FILE *       const file,
         break;
         
     default:
-        pm_error("bad magic number - not a PAM, PPM, PGM, or PBM file");
+        pm_error("bad magic number 0x%x - not a PAM, PPM, PGM, or PBM file",
+                 pamP->format);
     }
     
     pamP->bytes_per_sample = pnm_bytespersample(pamP->maxval);
@@ -848,18 +860,22 @@ pnm_writepaminit(struct pam * const pamP) {
 
     if (pamP->size < pamP->len)
         pm_error("pam object passed to pnm_writepaminit() is smaller "
-                 "(%d bytes, according to its 'size' element) "
+                 "(%u bytes, according to its 'size' element) "
                  "than the amount of data in it "
-                 "(%d bytes, according to its 'len' element).",
+                 "(%u bytes, according to its 'len' element).",
                  pamP->size, pamP->len);
 
-    if (pamP->len < PAM_STRUCT_SIZE(bytes_per_sample))
+    if (pamP->size < PAM_STRUCT_SIZE(bytes_per_sample))
         pm_error("pam object passed to pnm_writepaminit() is too small.  "
                  "It must be large\n"
                  "enough to hold at least up through the "
                  "'bytes_per_sample' member, but according\n"
-                 "to its 'len' member, it is only %d bytes long.", 
-                 pamP->len);
+                 "to its 'size' member, it is only %u bytes long.", 
+                 pamP->size);
+    if (pamP->len < PAM_STRUCT_SIZE(maxval))
+        pm_error("pam object must contain members at least through 'maxval', "
+                 "but according to the 'len' member, it is only %u bytes "
+                 "long.", pamP->len);
 
     if (pamP->maxval > PAM_OVERALL_MAXVAL)
         pm_error("maxval (%lu) passed to pnm_writepaminit() "
@@ -870,6 +886,8 @@ pnm_writepaminit(struct pam * const pamP) {
     else
         tupleType = pamP->tuple_type;
 
+    if (pamP->len < PAM_STRUCT_SIZE(bytes_per_sample))
+        pamP->len = PAM_STRUCT_SIZE(bytes_per_sample);
     pamP->bytes_per_sample = pnm_bytespersample(pamP->maxval);
     
     switch (PAM_FORMAT_TYPE(pamP->format)) {