9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] pngread: alloc chunk's length
@ 2021-07-10 21:28 adr via 9fans
  2021-07-10 21:49 ` adr via 9fans
  2021-07-12 16:01 ` ori
  0 siblings, 2 replies; 16+ messages in thread
From: adr via 9fans @ 2021-07-10 21:28 UTC (permalink / raw)
  To: 9fans

Hi,

Png is using a fix size to allocate space for the chunks. I noticed
it because it couldn't open some png files (the chunk size was
bigger than IDATSIZE).

This patch removes IDATSIZE and instead makes png to allocate the
size of the chunk before reading it.


--- sys/src/cmd/jpg/readpng.c   Thu Jan 24 23:39:55 2013
+++ /sys/src/cmd/jpg/readpng.c  Sat Jul 10 13:09:13 2021
@@ -10,8 +10,6 @@
 
 enum
 {
-       IDATSIZE = 1000000,
-
        /* filtering algorithms */
        FilterNone =    0,      /* new[x][y] = buf[x][y] */
        FilterSub =     1,      /* new[x][y] = buf[x][y] + new[x-1][y] */ 
@@ -51,7 +49,6 @@
 struct ZlibR
 {
        Biobuf *io;             /* input buffer */
-       uchar *buf;             /* malloc'ed staging buffer */
        uchar *p;                       /* next byte to decompress */
        uchar *e;                       /* end of buffer */
        ZlibW *w;
@@ -94,19 +91,26 @@
 }
 
 static int
-getchunk(Biobuf *b, char *type, uchar *d, int m)
+chunklen(Biobuf *b)
 {
-       uchar buf[8];
+       uchar buf[4];
+
+       if(Bread(b, buf, 4) != 4)
+               return -1;
+       return get4(buf);
+}
+
+static int
+getchunk(Biobuf *b, char *type, uchar *d, int n)
+{
+       uchar buf[4];
        ulong crc = 0, crc2;
-       int n, nr;
+       int nr;
 
-       if(Bread(b, buf, 8) != 8)
+       if(Bread(b, buf, 4) != 4)
                return -1;
-       n = get4(buf);
-       memmove(type, buf+4, 4);
+       memmove(type, buf, 4);
        type[4] = 0;
-       if(n > m)
-               sysfatal("getchunk needed %d, had %d", n, m);
        nr = Bread(b, d, n);
        if(nr != n)
                sysfatal("getchunk read %d, expected %d", nr, n);
@@ -117,7 +121,7 @@
        crc2 = get4(buf);
        if(crc != crc2)
                sysfatal("getchunk crc failed");
-       return n;
+       return 0;
 }
 
 static int
@@ -129,25 +133,31 @@
 
        if(z->p >= z->e){
        Again:
-               z->p = z->buf;
+               n = chunklen(z->io);
+               if(n < 0)
+                       return -1;
+               z->p = pngmalloc(n, 0);
                z->e = z->p;
-               n = getchunk(z->io, type, z->p, IDATSIZE);
-               if(n < 0 || strcmp(type, "IEND") == 0)
+               getchunk(z->io, type, z->p, n);
+               if(strcmp(type, "IEND") == 0){
+                       free(z->p);
                        return -1;
+               }
                z->e = z->p + n;
                if(!strcmp(type,"PLTE")){
                        if(n < 3 || n > 3*256 || n%3)
                                sysfatal("invalid PLTE chunk len %d", n);
                        memcpy(z->w->palette, z->p, n);
                        z->w->palsize = 256;
+                       free(z->p);
                        goto Again;
                }
-               if(type[0] & PropertyBit)
+               if(type[0] & PropertyBit){
+                       free(z->p);
                        goto Again;  /* skip auxiliary chunks fornow */
-               if(strcmp(type,"IDAT")){
-                       sysfatal("unrecognized mandatory chunk %s", type);
-                       goto Again;
                }
+               if(strcmp(type,"IDAT"))
+                       sysfatal("unrecognized mandatory chunk %s", type);
        }
        return *z->p++;
 }
@@ -383,18 +393,23 @@
 {
        char type[5];
        int bpc, colorfmt, dx, dy, err, n, nchan, nout, useadam7;
-       uchar *buf, *h;
+       uchar *buf, *mag, *h;
        Rawimage *image;
        ZlibR zr;
        ZlibW zw;
 
-       buf = pngmalloc(IDATSIZE, 0);
-       if(Bread(b, buf, sizeof PNGmagic) != sizeof PNGmagic ||
-           memcmp(PNGmagic, buf, sizeof PNGmagic) != 0)
+       mag = pngmalloc(sizeof PNGmagic, 0);
+       if(Bread(b, mag, sizeof PNGmagic) != sizeof PNGmagic ||
+           memcmp(PNGmagic, mag, sizeof PNGmagic) != 0)
                sysfatal("bad PNGmagic");
+       free(mag);
 
-       n = getchunk(b, type, buf, IDATSIZE);
-       if(n < 13 || strcmp(type,"IHDR") != 0)
+       n = chunklen(b);
+       if(n < 0)
+               sysfatal("missing IHDR chunk");
+       buf = pngmalloc(n, 0);
+       getchunk(b, type, buf, n);
+       if(strcmp(type,"IHDR") != 0)
                sysfatal("missing IHDR chunk");
        h = buf;
        dx = get4(h);
@@ -460,7 +475,7 @@
        memset(&zr, 0, sizeof zr);
        zr.w = &zw;
        zr.io = b;
-       zr.buf = buf;
+       free(buf);
 
        memset(&zw, 0, sizeof zw);
        if(useadam7)
@@ -483,7 +498,6 @@
        if(err)
                sysfatal("inflatezlib %s\n", flateerr(err));
 
-       free(buf);
        free(zw.scan);
        free(zw.lastscan);
        return image;

------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/T4a714ed14c50767a-Mdb82973047397d68fdedb7c3
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-07-14 17:05 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-10 21:28 [9fans] pngread: alloc chunk's length adr via 9fans
2021-07-10 21:49 ` adr via 9fans
2021-07-12 12:53   ` ori
2021-07-12 16:28     ` adr via 9fans
2021-07-12 16:01 ` ori
2021-07-12 17:01   ` adr via 9fans
2021-07-12 18:04     ` hiro
2021-07-12 23:31       ` adr via 9fans
2021-07-12 23:49         ` adr via 9fans
2021-07-13  8:16           ` hiro
2021-07-13  9:40             ` adr via 9fans
2021-07-13  9:46               ` hiro
2021-07-13 12:04                 ` adr via 9fans
2021-07-13 12:11                 ` adr via 9fans
2021-07-14 15:52     ` ori
2021-07-14 17:05       ` adr via 9fans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).