diff options
author | jbj <devnull@localhost> | 2004-09-19 16:14:54 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2004-09-19 16:14:54 +0000 |
commit | 40409429140f8db038e62291ba92630f3928ca74 (patch) | |
tree | 4a7ea4ef3a9df28f2bc857491f8d22786e4e28c2 /zlib/crc32.c | |
parent | 59293dd8928d6f0033a45fdef9e9f50a296a3a0b (diff) | |
download | librpm-tizen-40409429140f8db038e62291ba92630f3928ca74.tar.gz librpm-tizen-40409429140f8db038e62291ba92630f3928ca74.tar.bz2 librpm-tizen-40409429140f8db038e62291ba92630f3928ca74.zip |
- upgrade to pristine zlib-1.2.1.2.
CVS patchset: 7420
CVS date: 2004/09/19 16:14:54
Diffstat (limited to 'zlib/crc32.c')
-rw-r--r-- | zlib/crc32.c | 107 |
1 files changed, 67 insertions, 40 deletions
diff --git a/zlib/crc32.c b/zlib/crc32.c index 368061c9f..0e0488058 100644 --- a/zlib/crc32.c +++ b/zlib/crc32.c @@ -11,6 +11,14 @@ /* @(#) $Id$ */ +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection + on the static variables used to control the first-use generation of the crc + tables. Therefore if you #define DYNAMIC_CRC_TABLE, you should first call + get_crc_table() to initialize the tables before allowing more than on thread + to use crc32(). + */ + #ifdef MAKECRCH # include <stdio.h> # ifndef DYNAMIC_CRC_TABLE @@ -48,11 +56,9 @@ # define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ (((w)&0xff00)<<8)+(((w)&0xff)<<24)) local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)) - /*@*/; + const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)) - /*@*/; + const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 @@ -60,13 +66,11 @@ #ifdef DYNAMIC_CRC_TABLE -local int crc_table_empty = 1; +local volatile int crc_table_empty = 1; local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)) - /*@*/; +local void make_crc_table OF((void)); #ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)) - /*@*/; + local void write_table OF((FILE *, const unsigned long FAR *)); #endif /* MAKECRCH */ /* @@ -99,38 +103,51 @@ local void make_crc_table() { unsigned long c; int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ + unsigned long poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } #ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, and - then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } + /* generate crc for each value followed by one, two, and three zeros, and + then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } #endif /* BYFOUR */ - crc_table_empty = 0; + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not exactly efficient, but rare) */ + while (crc_table_empty) + ; + } #ifdef MAKECRCH /* write out CRC tables to crc32.h */ @@ -181,12 +198,13 @@ local void write_table(out, table) /* ========================================================================= * This function can be used by asm versions of crc32() */ -const unsigned long FAR * ZEXPORT get_crc_table(void) +const unsigned long FAR * ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) make_crc_table(); + if (crc_table_empty) + make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; + return (const unsigned long FAR *)crc_table; } /* ========================================================================= */ @@ -194,7 +212,10 @@ const unsigned long FAR * ZEXPORT get_crc_table(void) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ -unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, unsigned len) +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; { if (buf == Z_NULL) return 0UL; @@ -234,7 +255,10 @@ unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uns #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ -local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf, unsigned len) +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; { register u4 c; register const u4 FAR *buf4; @@ -271,7 +295,10 @@ local unsigned long crc32_little(unsigned long crc, const unsigned char FAR *buf #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ -local unsigned long crc32_big(unsigned long crc, const unsigned char FAR *buf, unsigned len) +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; { register u4 c; register const u4 FAR *buf4; |