From 84d5eb428747b48940a8939754c75911df637257 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 27 Nov 2018 19:22:15 +0000 Subject: [PATCH] Move the ZLIB_STANDALONE main() into its own file. Now, instead of getting the zlib test/helper program by manually compiling a source file with unusual options, it gets built as standard by the ordinary Makefile. --- .gitignore | 1 + Recipe | 1 + sshzlib.c | 106 ------------------------------------------------- testzlib.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 106 deletions(-) create mode 100644 testzlib.c diff --git a/.gitignore b/.gitignore index 890f8b23..5a61bf26 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ /unix/Pterm.app /fuzzterm /testbn +/testzlib /cgtest /*.DSA /*.RSA diff --git a/Recipe b/Recipe index 43c6582e..ef2c36a6 100644 --- a/Recipe +++ b/Recipe @@ -375,6 +375,7 @@ fuzzterm : [UT] UXTERM CHARSET misc version uxmisc uxucs fuzzterm time settings + uxstore be_none uxnogtk memory testbn : [UT] testbn sshbn MISC version CONF tree234 uxmisc uxnogtk testbn : [C] testbn sshbn MISC version CONF tree234 winmisc LIBS +testzlib : [UT] testzlib sshzlib memory uppity : [UT] uxserver SSHSERVER UXMISC uxsignal uxnoise uxgss uxnogtk + uxpty uxsftpserver ux_x11 uxagentsock diff --git a/sshzlib.c b/sshzlib.c index e20d9d04..0da52c0c 100644 --- a/sshzlib.c +++ b/sshzlib.c @@ -42,30 +42,7 @@ #include #include "defs.h" - -#ifdef ZLIB_STANDALONE - -/* - * This module also makes a handy zlib decoding tool for when - * you're picking apart Zip files or PDFs or PNGs. If you compile - * it with ZLIB_STANDALONE defined, it builds on its own and - * becomes a command-line utility. - * - * Therefore, here I provide a self-contained implementation of the - * macros required from the rest of the PuTTY sources. - */ -#define snew(type) ( (type *) malloc(sizeof(type)) ) -#define snewn(n, type) ( (type *) malloc((n) * sizeof(type)) ) -#define sresize(x, n, type) ( (type *) realloc((x), (n) * sizeof(type)) ) -#define sfree(x) ( free((x)) ) - -typedef struct { const struct dummy *vt; } ssh_compressor; -typedef struct { const struct dummy *vt; } ssh_decompressor; -static const struct dummy { int i; } ssh_zlib; - -#else #include "ssh.h" -#endif /* ---------------------------------------------------------------------- * Basic LZ77 code. This bit is designed modularly, so it could be @@ -1219,87 +1196,6 @@ bool zlib_decompress_block(ssh_decompressor *dc, return false; } -#ifdef ZLIB_STANDALONE - -#include -#include - -int main(int argc, char **argv) -{ - unsigned char buf[16], *outbuf; - int ret, outlen; - ssh_decompressor *handle; - int noheader = false, opts = true; - char *filename = NULL; - FILE *fp; - - while (--argc) { - char *p = *++argv; - - if (p[0] == '-' && opts) { - if (!strcmp(p, "-d")) - noheader = true; - else if (!strcmp(p, "--")) - opts = false; /* next thing is filename */ - else { - fprintf(stderr, "unknown command line option '%s'\n", p); - return 1; - } - } else if (!filename) { - filename = p; - } else { - fprintf(stderr, "can only handle one filename\n"); - return 1; - } - } - - handle = zlib_decompress_init(); - - if (noheader) { - /* - * Provide missing zlib header if -d was specified. - */ - zlib_decompress_block(handle, "\x78\x9C", 2, &outbuf, &outlen); - assert(outlen == 0); - } - - if (filename) - fp = fopen(filename, "rb"); - else - fp = stdin; - - if (!fp) { - assert(filename); - fprintf(stderr, "unable to open '%s'\n", filename); - return 1; - } - - while (1) { - ret = fread(buf, 1, sizeof(buf), fp); - if (ret <= 0) - break; - zlib_decompress_block(handle, buf, ret, &outbuf, &outlen); - if (outbuf) { - if (outlen) - fwrite(outbuf, 1, outlen, stdout); - sfree(outbuf); - } else { - fprintf(stderr, "decoding error\n"); - fclose(fp); - return 1; - } - } - - zlib_decompress_cleanup(handle); - - if (filename) - fclose(fp); - - return 0; -} - -#else - const struct ssh_compression_alg ssh_zlib = { "zlib", "zlib@openssh.com", /* delayed version */ @@ -1311,5 +1207,3 @@ const struct ssh_compression_alg ssh_zlib = { zlib_decompress_block, "zlib (RFC1950)" }; - -#endif diff --git a/testzlib.c b/testzlib.c new file mode 100644 index 00000000..cec31d12 --- /dev/null +++ b/testzlib.c @@ -0,0 +1,114 @@ +/* + * Main program to compile sshzlib.c into a zlib decoding tool. + * + * This is potentially a handy tool in its own right for picking apart + * Zip files or PDFs or PNGs, because it accepts the bare Deflate + * format and the zlib wrapper format, unlike 'zcat' which accepts + * only the gzip wrapper format. + * + * It's also useful as a means for a fuzzer to get reasonably direct + * access to PuTTY's zlib decompressor. + */ + +#include +#include +#include +#include + +#include "defs.h" +#include "ssh.h" + +void modalfatalbox(const char *p, ...) +{ + va_list ap; + fprintf(stderr, "FATAL ERROR: "); + va_start(ap, p); + vfprintf(stderr, p, ap); + va_end(ap); + fputc('\n', stderr); + exit(1); +} + +int main(int argc, char **argv) +{ + unsigned char buf[16], *outbuf; + int ret, outlen; + ssh_decompressor *handle; + int noheader = false, opts = true; + char *filename = NULL; + FILE *fp; + + while (--argc) { + char *p = *++argv; + + if (p[0] == '-' && opts) { + if (!strcmp(p, "-d")) { + noheader = true; + } else if (!strcmp(p, "--")) { + opts = false; /* next thing is filename */ + } else if (!strcmp(p, "--help")) { + printf("usage: testzlib decode zlib (RFC1950) data" + " from standard input\n"); + printf(" testzlib -d decode Deflate (RFC1951) data" + " from standard input\n"); + printf(" testzlib --help display this text\n"); + return 0; + } else { + fprintf(stderr, "unknown command line option '%s'\n", p); + return 1; + } + } else if (!filename) { + filename = p; + } else { + fprintf(stderr, "can only handle one filename\n"); + return 1; + } + } + + handle = ssh_decompressor_new(&ssh_zlib); + + if (noheader) { + /* + * Provide missing zlib header if -d was specified. + */ + static const unsigned char ersatz_zlib_header[] = { 0x78, 0x9C }; + ssh_decompressor_decompress( + handle, ersatz_zlib_header, sizeof(ersatz_zlib_header), + &outbuf, &outlen); + assert(outlen == 0); + } + + if (filename) + fp = fopen(filename, "rb"); + else + fp = stdin; + + if (!fp) { + assert(filename); + fprintf(stderr, "unable to open '%s'\n", filename); + return 1; + } + + while (1) { + ret = fread(buf, 1, sizeof(buf), fp); + if (ret <= 0) + break; + ssh_decompressor_decompress(handle, buf, ret, &outbuf, &outlen); + if (outbuf) { + if (outlen) + fwrite(outbuf, 1, outlen, stdout); + sfree(outbuf); + } else { + fprintf(stderr, "decoding error\n"); + fclose(fp); + return 1; + } + } + + ssh_decompressor_free(handle); + + if (filename) + fclose(fp); + + return 0; +}