xref: /openbsd-src/lib/libz/zutil.c (revision a04ea15dafe6974ae5a5b91b1adc9d00183fc2e9)
12af503bcStholo /* zutil.c -- target dependent utility functions for the compression library
236f395ceStb  * Copyright (C) 1995-2017 Jean-loup Gailly
32af503bcStholo  * For conditions of distribution and use, see copyright notice in zlib.h
42af503bcStholo  */
52af503bcStholo 
62af503bcStholo #include "zutil.h"
736f395ceStb #ifndef Z_SOLO
836f395ceStb #  include "gzguts.h"
985c48e79Shenning #endif
102af503bcStholo 
1136f395ceStb z_const char * const z_errmsg[10] = {
1236f395ceStb     (z_const char *)"need dictionary",     /* Z_NEED_DICT       2  */
1336f395ceStb     (z_const char *)"stream end",          /* Z_STREAM_END      1  */
1436f395ceStb     (z_const char *)"",                    /* Z_OK              0  */
1536f395ceStb     (z_const char *)"file error",          /* Z_ERRNO         (-1) */
1636f395ceStb     (z_const char *)"stream error",        /* Z_STREAM_ERROR  (-2) */
1736f395ceStb     (z_const char *)"data error",          /* Z_DATA_ERROR    (-3) */
1836f395ceStb     (z_const char *)"insufficient memory", /* Z_MEM_ERROR     (-4) */
1936f395ceStb     (z_const char *)"buffer error",        /* Z_BUF_ERROR     (-5) */
2036f395ceStb     (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
2136f395ceStb     (z_const char *)""
2236f395ceStb };
232af503bcStholo 
242af503bcStholo 
zlibVersion(void)25*a04ea15dStb const char * ZEXPORT zlibVersion(void) {
262af503bcStholo     return ZLIB_VERSION;
272af503bcStholo }
282af503bcStholo 
zlibCompileFlags(void)29*a04ea15dStb uLong ZEXPORT zlibCompileFlags(void) {
3085c48e79Shenning     uLong flags;
3185c48e79Shenning 
3285c48e79Shenning     flags = 0;
3336f395ceStb     switch ((int)(sizeof(uInt))) {
3485c48e79Shenning     case 2:     break;
3585c48e79Shenning     case 4:     flags += 1;     break;
3685c48e79Shenning     case 8:     flags += 2;     break;
3785c48e79Shenning     default:    flags += 3;
3885c48e79Shenning     }
3936f395ceStb     switch ((int)(sizeof(uLong))) {
4085c48e79Shenning     case 2:     break;
4185c48e79Shenning     case 4:     flags += 1 << 2;        break;
4285c48e79Shenning     case 8:     flags += 2 << 2;        break;
4385c48e79Shenning     default:    flags += 3 << 2;
4485c48e79Shenning     }
4536f395ceStb     switch ((int)(sizeof(voidpf))) {
4685c48e79Shenning     case 2:     break;
4785c48e79Shenning     case 4:     flags += 1 << 4;        break;
4885c48e79Shenning     case 8:     flags += 2 << 4;        break;
4985c48e79Shenning     default:    flags += 3 << 4;
5085c48e79Shenning     }
5136f395ceStb     switch ((int)(sizeof(z_off_t))) {
5285c48e79Shenning     case 2:     break;
5385c48e79Shenning     case 4:     flags += 1 << 6;        break;
5485c48e79Shenning     case 8:     flags += 2 << 6;        break;
5585c48e79Shenning     default:    flags += 3 << 6;
5685c48e79Shenning     }
5736f395ceStb #ifdef ZLIB_DEBUG
5885c48e79Shenning     flags += 1 << 8;
5985c48e79Shenning #endif
608bda5813Stb     /*
6185c48e79Shenning #if defined(ASMV) || defined(ASMINF)
6285c48e79Shenning     flags += 1 << 9;
6385c48e79Shenning #endif
648bda5813Stb      */
6585c48e79Shenning #ifdef ZLIB_WINAPI
6685c48e79Shenning     flags += 1 << 10;
6785c48e79Shenning #endif
6885c48e79Shenning #ifdef BUILDFIXED
6985c48e79Shenning     flags += 1 << 12;
7085c48e79Shenning #endif
7185c48e79Shenning #ifdef DYNAMIC_CRC_TABLE
7285c48e79Shenning     flags += 1 << 13;
7385c48e79Shenning #endif
7485c48e79Shenning #ifdef NO_GZCOMPRESS
75d76b9bfaSmillert     flags += 1L << 16;
7685c48e79Shenning #endif
7785c48e79Shenning #ifdef NO_GZIP
78d76b9bfaSmillert     flags += 1L << 17;
7985c48e79Shenning #endif
8085c48e79Shenning #ifdef PKZIP_BUG_WORKAROUND
81d76b9bfaSmillert     flags += 1L << 20;
8285c48e79Shenning #endif
8385c48e79Shenning #ifdef FASTEST
84d76b9bfaSmillert     flags += 1L << 21;
8585c48e79Shenning #endif
8636f395ceStb #if defined(STDC) || defined(Z_HAVE_STDARG_H)
8785c48e79Shenning #  ifdef NO_vsnprintf
88d76b9bfaSmillert     flags += 1L << 25;
8985c48e79Shenning #    ifdef HAS_vsprintf_void
90d76b9bfaSmillert     flags += 1L << 26;
9185c48e79Shenning #    endif
9285c48e79Shenning #  else
9385c48e79Shenning #    ifdef HAS_vsnprintf_void
94d76b9bfaSmillert     flags += 1L << 26;
9585c48e79Shenning #    endif
9685c48e79Shenning #  endif
9785c48e79Shenning #else
98d76b9bfaSmillert     flags += 1L << 24;
9985c48e79Shenning #  ifdef NO_snprintf
100d76b9bfaSmillert     flags += 1L << 25;
10185c48e79Shenning #    ifdef HAS_sprintf_void
102d76b9bfaSmillert     flags += 1L << 26;
10385c48e79Shenning #    endif
10485c48e79Shenning #  else
10585c48e79Shenning #    ifdef HAS_snprintf_void
106d76b9bfaSmillert     flags += 1L << 26;
10785c48e79Shenning #    endif
10885c48e79Shenning #  endif
10985c48e79Shenning #endif
11085c48e79Shenning     return flags;
11185c48e79Shenning }
11285c48e79Shenning 
11336f395ceStb #ifdef ZLIB_DEBUG
11436f395ceStb #include <stdlib.h>
11515ce0796Smillert #  ifndef verbose
11615ce0796Smillert #    define verbose 0
11715ce0796Smillert #  endif
11836f395ceStb int ZLIB_INTERNAL z_verbose = verbose;
11915ce0796Smillert 
z_error(char * m)120*a04ea15dStb void ZLIB_INTERNAL z_error(char *m) {
1212af503bcStholo     fprintf(stderr, "%s\n", m);
1222af503bcStholo     exit(1);
1232af503bcStholo }
124f503157cSmillert #endif
1252af503bcStholo 
12615ce0796Smillert /* exported to allow conversion of error code to string for compress() and
12715ce0796Smillert  * uncompress()
12815ce0796Smillert  */
zError(int err)129*a04ea15dStb const char * ZEXPORT zError(int err) {
13015ce0796Smillert     return ERR_MSG(err);
13115ce0796Smillert }
13215ce0796Smillert 
133703d4924Stb #if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
134703d4924Stb     /* The older Microsoft C Run-Time Library for Windows CE doesn't have
135d76b9bfaSmillert      * errno.  We define it as a global variable to simplify porting.
136d76b9bfaSmillert      * Its value is always 0 and should not be used.
137d76b9bfaSmillert      */
13885c48e79Shenning     int errno = 0;
13985c48e79Shenning #endif
14015ce0796Smillert 
1412af503bcStholo #ifndef HAVE_MEMCPY
1422af503bcStholo 
zmemcpy(Bytef * dest,const Bytef * source,uInt len)143*a04ea15dStb void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) {
1442af503bcStholo     if (len == 0) return;
1452af503bcStholo     do {
1462af503bcStholo         *dest++ = *source++; /* ??? to be unrolled */
1472af503bcStholo     } while (--len != 0);
1482af503bcStholo }
1492af503bcStholo 
zmemcmp(const Bytef * s1,const Bytef * s2,uInt len)150*a04ea15dStb int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) {
1512af503bcStholo     uInt j;
1522af503bcStholo 
1532af503bcStholo     for (j = 0; j < len; j++) {
1542af503bcStholo         if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
1552af503bcStholo     }
1562af503bcStholo     return 0;
1572af503bcStholo }
1582af503bcStholo 
zmemzero(Bytef * dest,uInt len)159*a04ea15dStb void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) {
1602af503bcStholo     if (len == 0) return;
1612af503bcStholo     do {
1622af503bcStholo         *dest++ = 0;  /* ??? to be unrolled */
1632af503bcStholo     } while (--len != 0);
1642af503bcStholo }
1652af503bcStholo #endif
1662af503bcStholo 
16736f395ceStb #ifndef Z_SOLO
16885c48e79Shenning 
16985c48e79Shenning #ifdef SYS16BIT
17085c48e79Shenning 
1712af503bcStholo #ifdef __TURBOC__
17285c48e79Shenning /* Turbo C in 16-bit mode */
17385c48e79Shenning 
1742af503bcStholo #  define MY_ZCALLOC
1752af503bcStholo 
1762af503bcStholo /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
1772af503bcStholo  * and farmalloc(64K) returns a pointer with an offset of 8, so we
1782af503bcStholo  * must fix the pointer. Warning: the pointer must be put back to its
1792af503bcStholo  * original form in order to free it, use zcfree().
1802af503bcStholo  */
1812af503bcStholo 
1822af503bcStholo #define MAX_PTR 10
1832af503bcStholo /* 10*64K = 640K */
1842af503bcStholo 
1852af503bcStholo local int next_ptr = 0;
1862af503bcStholo 
1872af503bcStholo typedef struct ptr_table_s {
1882af503bcStholo     voidpf org_ptr;
1892af503bcStholo     voidpf new_ptr;
1902af503bcStholo } ptr_table;
1912af503bcStholo 
1922af503bcStholo local ptr_table table[MAX_PTR];
1932af503bcStholo /* This table is used to remember the original form of pointers
1942af503bcStholo  * to large buffers (64K). Such pointers are normalized with a zero offset.
1952af503bcStholo  * Since MSDOS is not a preemptive multitasking OS, this table is not
1962af503bcStholo  * protected from concurrent access. This hack doesn't work anyway on
1972af503bcStholo  * a protected system like OS/2. Use Microsoft C instead.
1982af503bcStholo  */
1992af503bcStholo 
zcalloc(voidpf opaque,unsigned items,unsigned size)200*a04ea15dStb voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
20136f395ceStb     voidpf buf;
2022af503bcStholo     ulg bsize = (ulg)items*size;
2032af503bcStholo 
20436f395ceStb     (void)opaque;
20536f395ceStb 
2062af503bcStholo     /* If we allocate less than 65520 bytes, we assume that farmalloc
2072af503bcStholo      * will return a usable pointer which doesn't have to be normalized.
2082af503bcStholo      */
2092af503bcStholo     if (bsize < 65520L) {
2102af503bcStholo         buf = farmalloc(bsize);
2112af503bcStholo         if (*(ush*)&buf != 0) return buf;
2122af503bcStholo     } else {
2132af503bcStholo         buf = farmalloc(bsize + 16L);
2142af503bcStholo     }
2152af503bcStholo     if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
2162af503bcStholo     table[next_ptr].org_ptr = buf;
2172af503bcStholo 
2182af503bcStholo     /* Normalize the pointer to seg:0 */
2192af503bcStholo     *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
2202af503bcStholo     *(ush*)&buf = 0;
2212af503bcStholo     table[next_ptr++].new_ptr = buf;
2222af503bcStholo     return buf;
2232af503bcStholo }
2242af503bcStholo 
zcfree(voidpf opaque,voidpf ptr)225*a04ea15dStb void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
2262af503bcStholo     int n;
22736f395ceStb 
22836f395ceStb     (void)opaque;
22936f395ceStb 
2302af503bcStholo     if (*(ush*)&ptr != 0) { /* object < 64K */
2312af503bcStholo         farfree(ptr);
2322af503bcStholo         return;
2332af503bcStholo     }
2342af503bcStholo     /* Find the original pointer */
2352af503bcStholo     for (n = 0; n < next_ptr; n++) {
2362af503bcStholo         if (ptr != table[n].new_ptr) continue;
2372af503bcStholo 
2382af503bcStholo         farfree(table[n].org_ptr);
2392af503bcStholo         while (++n < next_ptr) {
2402af503bcStholo             table[n-1] = table[n];
2412af503bcStholo         }
2422af503bcStholo         next_ptr--;
2432af503bcStholo         return;
2442af503bcStholo     }
245f503157cSmillert     Assert(0, "zcfree: ptr not found");
2462af503bcStholo }
24785c48e79Shenning 
2482af503bcStholo #endif /* __TURBOC__ */
2492af503bcStholo 
2502af503bcStholo 
25185c48e79Shenning #ifdef M_I86
2522af503bcStholo /* Microsoft C in 16-bit mode */
2532af503bcStholo 
2542af503bcStholo #  define MY_ZCALLOC
2552af503bcStholo 
25615ce0796Smillert #if (!defined(_MSC_VER) || (_MSC_VER <= 600))
2572af503bcStholo #  define _halloc  halloc
2582af503bcStholo #  define _hfree   hfree
2592af503bcStholo #endif
2602af503bcStholo 
zcalloc(voidpf opaque,uInt items,uInt size)261*a04ea15dStb voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) {
26236f395ceStb     (void)opaque;
2632af503bcStholo     return _halloc((long)items, size);
2642af503bcStholo }
2652af503bcStholo 
zcfree(voidpf opaque,voidpf ptr)266*a04ea15dStb void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
26736f395ceStb     (void)opaque;
2682af503bcStholo     _hfree(ptr);
2692af503bcStholo }
2702af503bcStholo 
27185c48e79Shenning #endif /* M_I86 */
27285c48e79Shenning 
27385c48e79Shenning #endif /* SYS16BIT */
2742af503bcStholo 
2752af503bcStholo 
2762af503bcStholo #ifndef MY_ZCALLOC /* Any system without a special alloc function */
2772af503bcStholo 
2782af503bcStholo #ifndef STDC
279*a04ea15dStb extern voidp malloc(uInt size);
280*a04ea15dStb extern voidp calloc(uInt items, uInt size);
281*a04ea15dStb extern void free(voidpf ptr);
2822af503bcStholo #endif
2832af503bcStholo 
zcalloc(voidpf opaque,unsigned items,unsigned size)284*a04ea15dStb voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
28536f395ceStb     (void)opaque;
286d1dd7beaSderaadt     if (items == 0 || size == 0)
2873cb51852Sderaadt         return (NULL);
288d1dd7beaSderaadt     return reallocarray(NULL, items, size);
2892af503bcStholo }
2902af503bcStholo 
zcfree(voidpf opaque,voidpf ptr)291*a04ea15dStb void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
29236f395ceStb     (void)opaque;
2932af503bcStholo     free(ptr);
2942af503bcStholo }
2952af503bcStholo 
2962af503bcStholo #endif /* MY_ZCALLOC */
29736f395ceStb 
29836f395ceStb #endif /* !Z_SOLO */
299