diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:23:45 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-09 23:23:45 -0700 |
commit | 7a6955760ba950eb82f57929f8f6c9847c65f0af (patch) | |
tree | e2cd657aca6d606e0b28bf57fe45e914717a334c /crc32.c | |
parent | f0e76a6634eb26e3ddc6dfc6f2489553eff8c8f4 (diff) | |
download | zlib-7a6955760ba950eb82f57929f8f6c9847c65f0af.tar.gz zlib-7a6955760ba950eb82f57929f8f6c9847c65f0af.tar.bz2 zlib-7a6955760ba950eb82f57929f8f6c9847c65f0af.zip |
zlib 1.2.1.2v1.2.1.2
Diffstat (limited to 'crc32.c')
-rw-r--r-- | crc32.c | 78 |
1 files changed, 50 insertions, 28 deletions
@@ -11,6 +11,14 @@ | |||
11 | 11 | ||
12 | /* @(#) $Id$ */ | 12 | /* @(#) $Id$ */ |
13 | 13 | ||
14 | /* | ||
15 | Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection | ||
16 | on the static variables used to control the first-use generation of the crc | ||
17 | tables. Therefore if you #define DYNAMIC_CRC_TABLE, you should first call | ||
18 | get_crc_table() to initialize the tables before allowing more than on thread | ||
19 | to use crc32(). | ||
20 | */ | ||
21 | |||
14 | #ifdef MAKECRCH | 22 | #ifdef MAKECRCH |
15 | # include <stdio.h> | 23 | # include <stdio.h> |
16 | # ifndef DYNAMIC_CRC_TABLE | 24 | # ifndef DYNAMIC_CRC_TABLE |
@@ -58,7 +66,7 @@ | |||
58 | 66 | ||
59 | #ifdef DYNAMIC_CRC_TABLE | 67 | #ifdef DYNAMIC_CRC_TABLE |
60 | 68 | ||
61 | local int crc_table_empty = 1; | 69 | local volatile int crc_table_empty = 1; |
62 | local unsigned long FAR crc_table[TBLS][256]; | 70 | local unsigned long FAR crc_table[TBLS][256]; |
63 | local void make_crc_table OF((void)); | 71 | local void make_crc_table OF((void)); |
64 | #ifdef MAKECRCH | 72 | #ifdef MAKECRCH |
@@ -95,38 +103,51 @@ local void make_crc_table() | |||
95 | { | 103 | { |
96 | unsigned long c; | 104 | unsigned long c; |
97 | int n, k; | 105 | int n, k; |
98 | unsigned long poly; /* polynomial exclusive-or pattern */ | 106 | unsigned long poly; /* polynomial exclusive-or pattern */ |
99 | /* terms of polynomial defining this crc (except x^32): */ | 107 | /* terms of polynomial defining this crc (except x^32): */ |
108 | static volatile int first = 1; /* flag to limit concurrent making */ | ||
100 | static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; | 109 | static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; |
101 | 110 | ||
102 | /* make exclusive-or pattern from polynomial (0xedb88320UL) */ | 111 | /* See if another task is already doing this (not thread-safe, but better |
103 | poly = 0UL; | 112 | than nothing -- significantly reduces duration of vulnerability in |
104 | for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) | 113 | case the advice about DYNAMIC_CRC_TABLE is ignored) */ |
105 | poly |= 1UL << (31 - p[n]); | 114 | if (first) { |
106 | 115 | first = 0; | |
107 | /* generate a crc for every 8-bit value */ | 116 | |
108 | for (n = 0; n < 256; n++) { | 117 | /* make exclusive-or pattern from polynomial (0xedb88320UL) */ |
109 | c = (unsigned long)n; | 118 | poly = 0UL; |
110 | for (k = 0; k < 8; k++) | 119 | for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) |
111 | c = c & 1 ? poly ^ (c >> 1) : c >> 1; | 120 | poly |= 1UL << (31 - p[n]); |
112 | crc_table[0][n] = c; | 121 | |
113 | } | 122 | /* generate a crc for every 8-bit value */ |
123 | for (n = 0; n < 256; n++) { | ||
124 | c = (unsigned long)n; | ||
125 | for (k = 0; k < 8; k++) | ||
126 | c = c & 1 ? poly ^ (c >> 1) : c >> 1; | ||
127 | crc_table[0][n] = c; | ||
128 | } | ||
114 | 129 | ||
115 | #ifdef BYFOUR | 130 | #ifdef BYFOUR |
116 | /* generate crc for each value followed by one, two, and three zeros, and | 131 | /* generate crc for each value followed by one, two, and three zeros, and |
117 | then the byte reversal of those as well as the first table */ | 132 | then the byte reversal of those as well as the first table */ |
118 | for (n = 0; n < 256; n++) { | 133 | for (n = 0; n < 256; n++) { |
119 | c = crc_table[0][n]; | 134 | c = crc_table[0][n]; |
120 | crc_table[4][n] = REV(c); | 135 | crc_table[4][n] = REV(c); |
121 | for (k = 1; k < 4; k++) { | 136 | for (k = 1; k < 4; k++) { |
122 | c = crc_table[0][c & 0xff] ^ (c >> 8); | 137 | c = crc_table[0][c & 0xff] ^ (c >> 8); |
123 | crc_table[k][n] = c; | 138 | crc_table[k][n] = c; |
124 | crc_table[k + 4][n] = REV(c); | 139 | crc_table[k + 4][n] = REV(c); |
125 | } | 140 | } |
126 | } | 141 | } |
127 | #endif /* BYFOUR */ | 142 | #endif /* BYFOUR */ |
128 | 143 | ||
129 | crc_table_empty = 0; | 144 | crc_table_empty = 0; |
145 | } | ||
146 | else { /* not first */ | ||
147 | /* wait for the other guy to finish (not exactly efficient, but rare) */ | ||
148 | while (crc_table_empty) | ||
149 | ; | ||
150 | } | ||
130 | 151 | ||
131 | #ifdef MAKECRCH | 152 | #ifdef MAKECRCH |
132 | /* write out CRC tables to crc32.h */ | 153 | /* write out CRC tables to crc32.h */ |
@@ -180,9 +201,10 @@ local void write_table(out, table) | |||
180 | const unsigned long FAR * ZEXPORT get_crc_table() | 201 | const unsigned long FAR * ZEXPORT get_crc_table() |
181 | { | 202 | { |
182 | #ifdef DYNAMIC_CRC_TABLE | 203 | #ifdef DYNAMIC_CRC_TABLE |
183 | if (crc_table_empty) make_crc_table(); | 204 | if (crc_table_empty) |
205 | make_crc_table(); | ||
184 | #endif /* DYNAMIC_CRC_TABLE */ | 206 | #endif /* DYNAMIC_CRC_TABLE */ |
185 | return (const unsigned long FAR *)crc_table; | 207 | return (const unsigned long FAR *)crc_table; |
186 | } | 208 | } |
187 | 209 | ||
188 | /* ========================================================================= */ | 210 | /* ========================================================================= */ |