[hackers] [flate] sflate += pkzip stream || nsz

From: <hg_AT_suckless.org>
Date: Mon, 24 Aug 2009 08:47:59 +0000 (UTC)

changeset: 119:491a4d53bc9e
user: nsz <nszabolcs_AT_gmail.com>
date: Mon Aug 24 08:44:52 2009 +0200
files: sflate.c
description:
sflate += pkzip stream

diff -r f9e371f5cd64 -r 491a4d53bc9e sflate.c
--- a/sflate.c Sun Aug 23 20:58:30 2009 +0200
+++ b/sflate.c Mon Aug 24 08:44:52 2009 +0200
@@ -3,6 +3,28 @@
 #include <string.h>
 #include "flate.h"
 
+static void set32(uchar *p, uint n) {
+ p[0] = n >> 24;
+ p[1] = n >> 16;
+ p[2] = n >> 8;
+ p[3] = n;
+}
+
+static void set32le(uchar *p, uint n) {
+ p[0] = n;
+ p[1] = n >> 8;
+ p[2] = n >> 16;
+ p[3] = n >> 24;
+}
+
+static int check32(uchar *p, uint n) {
+ return n == ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+}
+
+static int check32le(uchar *p, uint n) {
+ return n == (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24));
+}
+
 enum {
         ZlibCM = 7 << 4,
         ZlibCINFO = 8,
@@ -22,10 +44,7 @@
 int deflate_zlib_footer(uchar *p, int n, uint sum, uint len, uint zlen) {
         if (n < 4)
                 return FlateErr;
- p[0] = sum >> 24;
- p[1] = sum >> 16;
- p[2] = sum >> 8;
- p[3] = sum;
+ set32(p, sum);
         return 4;
 }
 
@@ -42,8 +61,7 @@
 }
 
 int inflate_zlib_footer(uchar *p, int n, uint sum, uint len, uint zlen) {
- if (n < 4 ||
- sum != ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]))
+ if (n < 4 || !check32(p, sum))
                 return FlateErr;
         return 4;
 }
@@ -62,12 +80,9 @@
 };
 
 int deflate_gzip_header(uchar *p, int n) {
- int k;
-
         if (n < 10)
                 return FlateErr;
- for (k = 0; k < n; k++)
- p[k] = 0;
+ memset(p, 0, 10);
         p[0] = GZipID1;
         p[1] = GZipID2;
         p[2] = GZipCM;
@@ -79,14 +94,8 @@
 int deflate_gzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) {
         if (n < 8)
                 return FlateErr;
- p[0] = sum;
- p[1] = sum >> 8;
- p[2] = sum >> 16;
- p[3] = sum >> 24;
- p[4] = len;
- p[5] = len >> 8;
- p[6] = len >> 16;
- p[7] = len >> 24;
+ set32le(p, sum);
+ set32le(p+4, len);
         return 8;
 }
 
@@ -127,14 +136,118 @@
 }
 
 int inflate_gzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) {
- if (n < 8 ||
- sum != (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)) ||
- len != (p[4] | (p[5] << 8) | (p[6] << 16) | (p[7] << 24)))
+ if (n < 8 || !check32le(p, sum) || !check32le(p+4, len))
                 return FlateErr;
         return 8;
 }
 
 
+static char pkname[] = "sflate_stream";
+
+enum {
+ PKHeadID = 0x04034b50,
+ PKDataID = 0x08074b50,
+ PKDirID = 0x02014b50,
+ PKFootID = 0x06054b50,
+ PKVersion = 20,
+ PKFlag = 1 << 3,
+ PKMethod = 8,
+ PKDate = (2009 - 1980) << 25,
+ PKHeadSize = 30,
+ PKDirSize = 46,
+ PKNameLen = sizeof(pkname) - 1
+};
+
+int deflate_pkzip_header(uchar *p, int n) {
+ if (n < PKHeadSize + PKNameLen)
+ return FlateErr;
+ memset(p, 0, PKHeadSize);
+ set32le(p, PKHeadID);
+ set32le(p+4, PKVersion);
+ set32le(p+6, PKFlag);
+ set32le(p+8, PKMethod);
+ set32le(p+10, PKDate);
+ set32le(p+26, PKNameLen);
+ memcpy(p + PKHeadSize, pkname, PKNameLen);
+ return PKHeadSize + PKNameLen;
+}
+
+int deflate_pkzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) {
+ if (n < PKDirSize + PKNameLen + 22)
+ return FlateErr;
+/* if (n < 16 + PKDirSize + PKNameLen + 22)
+ return FlateErr;
+ set32le(p, PKDataID);
+ set32le(p+4, sum);
+ set32le(p+8, zlen);
+ set32le(p+12, len);
+ p += 16;
+*/
+ memset(p, 0, PKDirSize);
+ set32le(p, PKDirID);
+ set32le(p+4, PKVersion | (PKVersion << 16));
+ set32le(p+8, PKFlag);
+ set32le(p+10, PKMethod);
+ set32le(p+12, PKDate);
+ set32le(p+16, sum);
+ set32le(p+20, zlen);
+ set32le(p+24, len);
+ set32le(p+28, PKNameLen);
+ memcpy(p + PKDirSize, pkname, PKNameLen);
+ p += PKDirSize + PKNameLen;
+ memset(p, 0, 22);
+ set32le(p, PKFootID);
+ p[8] = p[10] = 1;
+ set32le(p+12, PKDirSize + PKNameLen);
+ set32le(p+16, zlen + PKHeadSize + PKNameLen);
+ return PKDirSize + PKNameLen + 22;
+/* set32le(p+12, 16 + PKDirSize + PKNameLen);
+ set32le(p+16, zlen + PKHeadSize + PKNameLen);
+ return 16 + PKDirSize + PKNameLen + 22;
+*/
+}
+
+int inflate_pkzip_header(uchar *p, int n) {
+ int k = 30;
+
+ if (k > n)
+ return FlateErr;
+ if (!check32le(p, PKHeadID))
+ return FlateErr;
+ if ((p[4] | (p[5] << 8)) > PKVersion)
+ return FlateErr;
+ if ((p[8] | (p[9] << 8)) != PKMethod)
+ return FlateErr;
+ k += p[26] | (p[27] << 8);
+ k += p[28] | (p[29] << 8);
+ if (k > n)
+ return FlateErr;
+ return k;
+}
+
+int inflate_pkzip_footer(uchar *p, int n, uint sum, uint len, uint zlen) {
+ int k = PKDirSize + 22;
+
+ if (k > n)
+ return FlateErr;
+ if (check32le(p, PKDataID)) {
+ p += 16;
+ k += 16;
+ if (k > n)
+ return FlateErr;
+ }
+ if (!check32le(p, PKDirID))
+ return FlateErr;
+ if (!check32le(p+16, sum))
+ return FlateErr;
+ if (!check32le(p+20, zlen))
+ return FlateErr;
+ if (!check32le(p+24, len))
+ return FlateErr;
+ return k;
+}
+
+
 /* example usage */
 
 static int (*header)(uchar *, int);
@@ -343,6 +456,17 @@
                 n = call(stdin, stdout);
                 break;
         case 'p':
+ if (comp == 'c') {
+ header = deflate_pkzip_header;
+ footer = deflate_pkzip_footer;
+ } else {
+ header = inflate_pkzip_header;
+ footer = inflate_pkzip_footer;
+ }
+ checksum = crc32;
+ crc32init();
+ n = call(stdin, stdout);
+ break;
         default:
                 err = "uninplemented.";
                 n = FlateErr;
Received on Mon Aug 24 2009 - 08:47:59 UTC

This archive was generated by hypermail 2.2.0 : Mon Aug 24 2009 - 09:00:07 UTC