summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-28 00:35:09 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-28 00:35:09 +0000
commit8057dadcea6e36451359362458275b1423ed6f5a (patch)
tree177d22c69821d23daf2bdcb7b4ff875a817d4098
parent1239e944d019142d816dec8b897b53d7462584a5 (diff)
downloadchromium_src-8057dadcea6e36451359362458275b1423ed6f5a.zip
chromium_src-8057dadcea6e36451359362458275b1423ed6f5a.tar.gz
chromium_src-8057dadcea6e36451359362458275b1423ed6f5a.tar.bz2
Revert 153496 - Merge 151720 - net: workaround compression leaks
(This is a reland of r151502, which was reverted in r151517 because it broke the Linux Official build.) This may break the Official build for a brief window while a two-sided patch lands. BUG=139744 Review URL: https://chromiumcodereview.appspot.com/10837057 TBR=agl@chromium.org Review URL: https://chromiumcodereview.appspot.com/10874087 TBR=agl@chromium.org Review URL: https://chromiumcodereview.appspot.com/10880081 git-svn-id: svn://svn.chromium.org/chrome/branches/1180/src@153595 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/spdy/buffered_spdy_framer.cc5
-rw-r--r--net/spdy/buffered_spdy_framer.h1
-rw-r--r--net/spdy/spdy_framer.cc178
-rw-r--r--net/spdy/spdy_framer.h10
-rw-r--r--net/spdy/spdy_framer_test.cc80
-rw-r--r--third_party/zlib/README.chromium3
-rw-r--r--third_party/zlib/deflate.c250
-rw-r--r--third_party/zlib/deflate.h5
-rw-r--r--third_party/zlib/mixed-source.patch491
-rw-r--r--third_party/zlib/zlib.gyp10
-rw-r--r--third_party/zlib/zlib.h12
11 files changed, 89 insertions, 956 deletions
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
index 91eadbd..b544dcb 100644
--- a/net/spdy/buffered_spdy_framer.cc
+++ b/net/spdy/buffered_spdy_framer.cc
@@ -252,6 +252,11 @@ bool BufferedSpdyFramer::IsCompressible(const SpdyFrame& frame) const {
return spdy_framer_.IsCompressible(frame);
}
+SpdyControlFrame* BufferedSpdyFramer::CompressControlFrame(
+ const SpdyControlFrame& frame) {
+ return spdy_framer_.CompressControlFrame(frame);
+}
+
// static
void BufferedSpdyFramer::set_enable_compression_default(bool value) {
g_enable_compression_default = value;
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h
index 0fc6fa7..494238e 100644
--- a/net/spdy/buffered_spdy_framer.h
+++ b/net/spdy/buffered_spdy_framer.h
@@ -143,6 +143,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer
SpdyDataFlags flags);
SpdyPriority GetHighestPriority() const;
bool IsCompressible(const SpdyFrame& frame) const;
+ SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame);
// Specify if newly created SpdySessions should have compression enabled.
static void set_enable_compression_default(bool value);
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index a1fc5eea..3a2ad73 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -661,155 +661,6 @@ void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
}
}
-// These constants are used by zlib to differentiate between normal data and
-// cookie data. Cookie data is handled specially by zlib when compressing.
-enum ZDataClass {
- // kZStandardData is compressed normally, save that it will never match
- // against any other class of data in the window.
- kZStandardData = Z_CLASS_STANDARD,
- // kZCookieData is compressed in its own Huffman blocks and only matches in
- // its entirety and only against other kZCookieData blocks. Any matches must
- // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
- // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
- // prefix matches.
- kZCookieData = Z_CLASS_COOKIE,
- // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
- // against the window.
- kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
-};
-
-// WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
-// needed when switching between classes of data.
-static void WriteZ(const base::StringPiece& data,
- ZDataClass clas,
- z_stream* out) {
- int rv;
-
- // If we are switching from standard to non-standard data then we need to end
- // the current Huffman context to avoid it leaking between them.
- if (out->clas == kZStandardData &&
- clas != kZStandardData) {
- out->avail_in = 0;
- rv = deflate(out, Z_PARTIAL_FLUSH);
- DCHECK_EQ(Z_OK, rv);
- DCHECK_EQ(0u, out->avail_in);
- DCHECK_LT(0u, out->avail_out);
- }
-
- out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
- out->avail_in = data.size();
- out->clas = clas;
- if (clas == kZStandardData) {
- rv = deflate(out, Z_NO_FLUSH);
- } else {
- rv = deflate(out, Z_PARTIAL_FLUSH);
- }
- DCHECK_EQ(Z_OK, rv);
- DCHECK_EQ(0u, out->avail_in);
- DCHECK_LT(0u, out->avail_out);
-}
-
-// WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
-static void WriteLengthZ(size_t n,
- unsigned length,
- ZDataClass clas,
- z_stream* out) {
- char buf[4];
- DCHECK_LE(length, sizeof(buf));
- for (unsigned i = 1; i <= length; i++) {
- buf[length - i] = n;
- n >>= 8;
- }
- WriteZ(base::StringPiece(buf, length), clas, out);
-}
-
-// WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
-// manner that resists the length of the compressed data from compromising
-// cookie data.
-void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
- z_stream* z) const {
- unsigned length_length = 4;
- if (spdy_version_ < 3)
- length_length = 2;
-
- WriteLengthZ(headers->size(), length_length, kZStandardData, z);
-
- std::map<std::string, std::string>::const_iterator it;
- for (it = headers->begin(); it != headers->end(); ++it) {
- WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
- WriteZ(it->first, kZStandardData, z);
-
- if (it->first == "cookie") {
- // We require the cookie values to end with a semi-colon and (save for
- // the first) to start with one too. The values are already separated by
- // semicolons in the header, but there's usually whitespace in there too.
- // So we accumulate the values without whitespace in |cookie_values| and
- // write them out, along with a final semicolon to terminate the last
- // cookie.
-
- std::string last_cookie;
- std::vector<base::StringPiece> cookie_values;
- size_t cookie_length = 0;
- base::StringPiece cookie_data(it->second);
-
- for (;;) {
- while (!cookie_data.empty() &&
- (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
- cookie_data.remove_prefix(1);
- }
- if (cookie_data.empty())
- break;
-
- size_t i;
- for (i = 0; i < cookie_data.size(); i++) {
- if (cookie_data[i] == ';')
- break;
- }
- if (i < cookie_data.size()) {
- cookie_values.push_back(cookie_data.substr(0, i+1));
- cookie_length += i+1;
- cookie_data.remove_prefix(i + 1);
- } else {
- last_cookie = cookie_data.as_string() + ";";
- cookie_values.push_back(last_cookie);
- cookie_length += last_cookie.size();
- cookie_data.remove_prefix(i);
- }
- }
-
- WriteLengthZ(cookie_length, length_length, kZStandardData, z);
- for (std::vector<base::StringPiece>::const_iterator
- i = cookie_values.begin(); i != cookie_values.end(); i++) {
- WriteZ(*i, kZCookieData, z);
- }
- } else if (it->first == "accept" ||
- it->first == "accept-charset" ||
- it->first == "accept-encoding" ||
- it->first == "accept-language" ||
- it->first == "host" ||
- it->first == "version" ||
- it->first == "method" ||
- it->first == "scheme" ||
- it->first == ":host" ||
- it->first == ":version" ||
- it->first == ":method" ||
- it->first == ":scheme" ||
- it->first == "user-agent") {
- WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
- WriteZ(it->second, kZStandardData, z);
- } else {
- // Non-whitelisted headers are Huffman compressed in their own block, but
- // don't match against the window.
- WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
- WriteZ(it->second, kZHuffmanOnlyData, z);
- }
- }
-
- z->avail_in = 0;
- int rv = deflate(z, Z_SYNC_FLUSH);
- DCHECK_EQ(Z_OK, rv);
- z->clas = kZStandardData;
-}
size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
size_t len) {
@@ -1202,7 +1053,7 @@ SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
if (compressed) {
return reinterpret_cast<SpdySynStreamControlFrame*>(
- CompressControlFrame(*syn_frame.get(), headers));
+ CompressControlFrame(*syn_frame.get()));
}
return syn_frame.release();
}
@@ -1235,7 +1086,7 @@ SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
if (compressed) {
return reinterpret_cast<SpdySynReplyControlFrame*>(
- CompressControlFrame(*reply_frame.get(), headers));
+ CompressControlFrame(*reply_frame.get()));
}
return reply_frame.release();
}
@@ -1331,7 +1182,7 @@ SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(
reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
if (compressed) {
return reinterpret_cast<SpdyHeadersControlFrame*>(
- CompressControlFrame(*headers_frame.get(), headers));
+ CompressControlFrame(*headers_frame.get()));
}
return headers_frame.release();
}
@@ -1511,8 +1362,7 @@ bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame,
}
SpdyControlFrame* SpdyFramer::CompressControlFrame(
- const SpdyControlFrame& frame,
- const SpdyHeaderBlock* headers) {
+ const SpdyControlFrame& frame) {
z_stream* compressor = GetHeaderCompressor();
if (!compressor)
return NULL;
@@ -1533,10 +1383,6 @@ SpdyControlFrame* SpdyFramer::CompressControlFrame(
// Create an output frame.
int compressed_max_size = deflateBound(compressor, payload_length);
- // Since we'll be performing lots of flushes when compressing the data,
- // zlib's lower bounds may be insufficient.
- compressed_max_size *= 2;
-
size_t new_frame_size = header_length + compressed_max_size;
if ((frame.type() == SYN_REPLY || frame.type() == HEADERS) &&
spdy_version_ < 3) {
@@ -1547,10 +1393,24 @@ SpdyControlFrame* SpdyFramer::CompressControlFrame(
memcpy(new_frame->data(), frame.data(),
frame.length() + SpdyFrame::kHeaderSize);
+ compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
+ compressor->avail_in = payload_length;
compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) +
header_length;
compressor->avail_out = compressed_max_size;
- WriteHeaderBlockToZ(headers, compressor);
+
+ // Make sure that all the data we pass to zlib is defined.
+ // This way, all Valgrind reports on the compressed data are zlib's fault.
+ (void)VALGRIND_CHECK_MEM_IS_DEFINED(compressor->next_in,
+ compressor->avail_in);
+
+ int rv = deflate(compressor, Z_SYNC_FLUSH);
+ if (rv != Z_OK) { // How can we know that it compressed everything?
+ // This shouldn't happen, right?
+ LOG(WARNING) << "deflate failure: " << rv;
+ return NULL;
+ }
+
int compressed_size = compressed_max_size - compressor->avail_out;
// We trust zlib. Also, we can't do anything about it.
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 1970838..63570a6 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -386,6 +386,9 @@ class NET_EXPORT_PRIVATE SpdyFramer {
// Returns true if a frame could be compressed.
bool IsCompressible(const SpdyFrame& frame) const;
+ // Returns a new SpdyControlFrame with the compressed payload of |frame|.
+ SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame);
+
// Get the minimum size of the control frame for the given control frame
// type. This is useful for validating frame blocks.
static size_t GetMinimumControlFrameSize(int version, SpdyControlType type);
@@ -494,9 +497,6 @@ class NET_EXPORT_PRIVATE SpdyFramer {
void WriteHeaderBlock(SpdyFrameBuilder* frame,
const SpdyHeaderBlock* headers) const;
- void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
- z_stream* out) const;
-
// Set the error code and moves the framer into the error state.
void set_error(SpdyError error);
@@ -505,10 +505,6 @@ class NET_EXPORT_PRIVATE SpdyFramer {
bool GetFrameBoundaries(const SpdyFrame& frame, int* payload_length,
int* header_length, const char** payload) const;
- // Returns a new SpdyControlFrame with the compressed payload of |frame|.
- SpdyControlFrame* CompressControlFrame(const SpdyControlFrame& frame,
- const SpdyHeaderBlock* headers);
-
// The size of the control frame buffer.
// Since this is only used for control frame headers, the maximum control
// frame header size (SYN_STREAM) is sufficient; all remaining control
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index ab021a9..fd80da4 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -1586,39 +1586,31 @@ TEST_P(SpdyFramerTest, CreateSynStreamCompressed) {
const SpdyPriority priority = IsSpdy2() ? 2 : 4;
const unsigned char kV2FrameData[] = {
0x80, spdy_version_, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x36,
+ 0x00, 0x00, 0x00, 0x25,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x38, 0xea,
0xdf, 0xa2, 0x51, 0xb2,
0x62, 0x60, 0x62, 0x60,
0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x4e,
- 0xcb, 0xcf, 0x67, 0x60,
- 0x06, 0x08, 0xa0, 0xa4,
- 0xc4, 0x22, 0x80, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xff, 0xff,
+ 0x60, 0x4e, 0xcb, 0xcf,
+ 0x87, 0x12, 0x40, 0x2e,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff
};
const unsigned char kV3FrameData[] = {
0x80, spdy_version_, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x37,
+ 0x00, 0x00, 0x00, 0x27,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x38, 0xEA,
0xE3, 0xC6, 0xA7, 0xC2,
0x02, 0xE5, 0x0E, 0x50,
0xC2, 0x4B, 0x4A, 0x04,
- 0xE5, 0x0B, 0x66, 0x80,
- 0x00, 0x4A, 0xCB, 0xCF,
- 0x07, 0x08, 0x20, 0x10,
- 0x95, 0x96, 0x9F, 0x0F,
- 0xA2, 0x00, 0x02, 0x28,
- 0x29, 0xB1, 0x08, 0x20,
- 0x80, 0x00, 0x00, 0x00,
- 0x00, 0xFF, 0xFF,
+ 0xE5, 0x0B, 0xE6, 0xB4,
+ 0xFC, 0x7C, 0x24, 0x0A,
+ 0x28, 0x08, 0x00, 0x00,
+ 0x00, 0xFF, 0xFF
};
scoped_ptr<SpdyFrame> frame(
framer.CreateSynStream(1, // stream id
@@ -1772,37 +1764,29 @@ TEST_P(SpdyFramerTest, CreateSynReplyCompressed) {
const unsigned char kV2FrameData[] = {
0x80, spdy_version_, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x38, 0xea,
0xdf, 0xa2, 0x51, 0xb2,
0x62, 0x60, 0x62, 0x60,
0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x4e,
- 0xcb, 0xcf, 0x67, 0x60,
- 0x06, 0x08, 0xa0, 0xa4,
- 0xc4, 0x22, 0x80, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xff, 0xff,
+ 0x60, 0x4e, 0xcb, 0xcf,
+ 0x87, 0x12, 0x40, 0x2e,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff
};
const unsigned char kV3FrameData[] = {
0x80, spdy_version_, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x01,
0x38, 0xea, 0xe3, 0xc6,
0xa7, 0xc2, 0x02, 0xe5,
0x0e, 0x50, 0xc2, 0x4b,
0x4a, 0x04, 0xe5, 0x0b,
- 0x66, 0x80, 0x00, 0x4a,
- 0xcb, 0xcf, 0x07, 0x08,
- 0x20, 0x10, 0x95, 0x96,
- 0x9f, 0x0f, 0xa2, 0x00,
- 0x02, 0x28, 0x29, 0xb1,
- 0x08, 0x20, 0x80, 0x00,
+ 0xe6, 0xb4, 0xfc, 0x7c,
+ 0x24, 0x0a, 0x28, 0x08,
0x00, 0x00, 0x00, 0xff,
- 0xff,
+ 0xff
};
scoped_ptr<SpdyFrame> frame(framer.CreateSynReply(
1, CONTROL_FLAG_NONE, true, &headers));
@@ -2164,37 +2148,29 @@ TEST_P(SpdyFramerTest, CreateHeadersCompressed) {
const unsigned char kV2FrameData[] = {
0x80, spdy_version_, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x38, 0xea,
0xdf, 0xa2, 0x51, 0xb2,
0x62, 0x60, 0x62, 0x60,
0x4e, 0x4a, 0x2c, 0x62,
- 0x60, 0x06, 0x08, 0xa0,
- 0xb4, 0xfc, 0x7c, 0x80,
- 0x00, 0x62, 0x60, 0x4e,
- 0xcb, 0xcf, 0x67, 0x60,
- 0x06, 0x08, 0xa0, 0xa4,
- 0xc4, 0x22, 0x80, 0x00,
- 0x02, 0x00, 0x00, 0x00,
- 0xff, 0xff,
+ 0x60, 0x4e, 0xcb, 0xcf,
+ 0x87, 0x12, 0x40, 0x2e,
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff
};
const unsigned char kV3FrameData[] = {
0x80, spdy_version_, 0x00, 0x08,
- 0x00, 0x00, 0x00, 0x31,
+ 0x00, 0x00, 0x00, 0x21,
0x00, 0x00, 0x00, 0x01,
0x38, 0xea, 0xe3, 0xc6,
0xa7, 0xc2, 0x02, 0xe5,
0x0e, 0x50, 0xc2, 0x4b,
0x4a, 0x04, 0xe5, 0x0b,
- 0x66, 0x80, 0x00, 0x4a,
- 0xcb, 0xcf, 0x07, 0x08,
- 0x20, 0x10, 0x95, 0x96,
- 0x9f, 0x0f, 0xa2, 0x00,
- 0x02, 0x28, 0x29, 0xb1,
- 0x08, 0x20, 0x80, 0x00,
+ 0xe6, 0xb4, 0xfc, 0x7c,
+ 0x24, 0x0a, 0x28, 0x08,
0x00, 0x00, 0x00, 0xff,
- 0xff,
+ 0xff
};
scoped_ptr<SpdyFrame> frame(framer.CreateHeaders(
1, CONTROL_FLAG_NONE, true, &headers));
diff --git a/third_party/zlib/README.chromium b/third_party/zlib/README.chromium
index 05016f1..9fc04d1 100644
--- a/third_party/zlib/README.chromium
+++ b/third_party/zlib/README.chromium
@@ -14,6 +14,3 @@ A few minor changes, all marked with "Google":
- Added 'mozzconf.h' to mangle the function names.
- Added an #ifdef to prevent zlib.h from mangling its functions.
The 'google.patch' file represents our changes from the original zlib-1.2.5.
-
-A more significant change to support mixed-source data compression. See
-crbug.com/139744 and mixed-source.patch.
diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c
index 02d1516..5c4022f 100644
--- a/third_party/zlib/deflate.c
+++ b/third_party/zlib/deflate.c
@@ -70,15 +70,14 @@ typedef enum {
finish_done /* finish done, accept no more input or output */
} block_state;
-typedef block_state (*compress_func) OF((deflate_state *s, int flush,
- int clas));
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
/* Compression function. Returns the block state after the call. */
local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush, int clas));
-local block_state deflate_fast OF((deflate_state *s, int flush, int clas));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
#ifndef FASTEST
-local block_state deflate_slow OF((deflate_state *s, int flush, int clas));
+local block_state deflate_slow OF((deflate_state *s, int flush));
#endif
local block_state deflate_rle OF((deflate_state *s, int flush));
local block_state deflate_huff OF((deflate_state *s, int flush));
@@ -88,9 +87,9 @@ local void flush_pending OF((z_streamp strm));
local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
#ifdef ASMV
void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match, int clas));
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match, int clas));
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
#endif
#ifdef DEBUG
@@ -282,9 +281,6 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
- s->class_bitmap = NULL;
- zmemzero(&s->cookie_locations, sizeof(s->cookie_locations));
- strm->clas = 0;
s->high_water = 0; /* nothing written to s->window yet */
@@ -371,8 +367,6 @@ int ZEXPORT deflateReset (strm)
s = (deflate_state *)strm->state;
s->pending = 0;
s->pending_out = s->pending_buf;
- TRY_FREE(strm, s->class_bitmap);
- s->class_bitmap = NULL;
if (s->wrap < 0) {
s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
@@ -823,26 +817,9 @@ int ZEXPORT deflate (strm, flush)
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
block_state bstate;
- if (strm->clas && s->class_bitmap == NULL) {
- /* This is the first time that we have seen alternative class
- * data. All data up till this point has been standard class. */
- s->class_bitmap = (Bytef*) ZALLOC(strm, s->w_size/4, sizeof(Byte));
- zmemzero(s->class_bitmap, s->w_size/4);
- }
-
- if (strm->clas && s->strategy == Z_RLE) {
- /* We haven't patched deflate_rle. */
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- if (s->strategy == Z_HUFFMAN_ONLY) {
- bstate = deflate_huff(s, flush);
- } else if (s->strategy == Z_RLE) {
- bstate = deflate_rle(s, flush);
- } else {
- bstate = (*(configuration_table[s->level].func))
- (s, flush, strm->clas);
- }
+ bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+ (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+ (*(configuration_table[s->level].func))(s, flush));
if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE;
@@ -938,7 +915,6 @@ int ZEXPORT deflateEnd (strm)
TRY_FREE(strm, strm->state->head);
TRY_FREE(strm, strm->state->prev);
TRY_FREE(strm, strm->state->window);
- TRY_FREE(strm, strm->state->class_bitmap);
ZFREE(strm, strm->state);
strm->state = Z_NULL;
@@ -1070,57 +1046,6 @@ local void lm_init (s)
#endif
}
-/* class_set sets bits [offset,offset+len) in s->class_bitmap to either 1 (if
- * class != 0) or 0 (otherwise). */
-local void class_set(s, offset, len, clas)
- deflate_state *s;
- IPos offset;
- uInt len;
- int clas;
-{
- IPos byte = offset >> 3;
- IPos bit = offset & 7;
- Bytef class_byte_value = clas ? 0xff : 0x00;
- Bytef class_bit_value = clas ? 1 : 0;
- static const Bytef mask[8] = {0xfe, 0xfd, 0xfb, 0xf7,
- 0xef, 0xdf, 0xbf, 0x7f};
-
- if (bit) {
- while (len) {
- s->class_bitmap[byte] &= mask[bit];
- s->class_bitmap[byte] |= class_bit_value << bit;
- bit++;
- len--;
- if (bit == 8) {
- bit = 0;
- byte++;
- break;
- }
- }
- }
-
- while (len >= 8) {
- s->class_bitmap[byte++] = class_byte_value;
- len -= 8;
- }
-
- while (len) {
- s->class_bitmap[byte] &= mask[bit];
- s->class_bitmap[byte] |= class_bit_value << bit;
- bit++;
- len--;
- }
-}
-
-local int class_at(s, window_offset)
- deflate_state *s;
- IPos window_offset;
-{
- IPos byte = window_offset >> 3;
- IPos bit = window_offset & 7;
- return (s->class_bitmap[byte] >> bit) & 1;
-}
-
#ifndef FASTEST
/* ===========================================================================
* Set match_start to the longest match starting at the given string and
@@ -1135,10 +1060,9 @@ local int class_at(s, window_offset)
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
* match.S. The code will be functionally equivalent.
*/
-local uInt longest_match(s, cur_match, clas)
+local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
- int clas;
{
unsigned chain_length = s->max_chain_length;/* max hash chain length */
register Bytef *scan = s->window + s->strstart; /* current string */
@@ -1186,9 +1110,6 @@ local uInt longest_match(s, cur_match, clas)
do {
Assert(cur_match < s->strstart, "no future");
match = s->window + cur_match;
- /* If the matched data is in the wrong class, skip it. */
- if (s->class_bitmap && class_at(s, cur_match) != clas)
- continue;
/* Skip to next match if the match length cannot increase
* or if the match length is less than 2. Note that the checks below
@@ -1231,8 +1152,6 @@ local uInt longest_match(s, cur_match, clas)
len = (MAX_MATCH - 1) - (int)(strend-scan);
scan = strend - (MAX_MATCH-1);
-#error "UNALIGNED_OK hasn't been patched."
-
#else /* UNALIGNED_OK */
if (match[best_len] != scan_end ||
@@ -1249,23 +1168,15 @@ local uInt longest_match(s, cur_match, clas)
scan += 2, match++;
Assert(*scan == *match, "match[2]?");
- if (!s->class_bitmap) {
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
- } else {
- /* We have to be mindful of the class of the data and not stray. */
- do {
- } while (*++scan == *++match &&
- class_at(s, match - s->window) == clas &&
- scan < strend);
- }
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
@@ -1293,67 +1204,20 @@ local uInt longest_match(s, cur_match, clas)
}
#endif /* ASMV */
-/* cookie_match is a replacement for longest_match in the case of cookie data.
- * Here we only wish to match the entire value so trying the partial matches in
- * longest_match is both wasteful and often fails to find the correct match.
- *
- * So we take the djb2 hash of the cookie and look up the last position for a
- * match in a special hash table. */
-local uInt cookie_match(s, start, len)
- deflate_state *s;
- IPos start;
- unsigned len;
-{
- unsigned hash = 5381;
- Bytef *str = s->window + start;
- unsigned i;
- IPos cookie_location;
-
- if (len >= MAX_MATCH)
- return 0;
-
- for (i = 0; i < len; i++)
- hash = ((hash << 5) + hash) + str[i];
-
- hash &= Z_COOKIE_HASH_MASK;
- cookie_location = s->cookie_locations[hash];
- s->cookie_locations[hash] = start;
- s->match_start = 0;
- if (cookie_location &&
- (start - cookie_location) > len &&
- (start - cookie_location) < MAX_DIST(s) &&
- len <= s->lookahead) {
- for (i = 0; i < len; i++) {
- if (s->window[start+i] != s->window[cookie_location+i] ||
- class_at(s, cookie_location+i) != 1) {
- return 0;
- }
- }
- s->match_start = cookie_location;
- return len;
- }
-
- return 0;
-}
-
-
#else /* FASTEST */
/* ---------------------------------------------------------------------------
* Optimized version for FASTEST only
*/
-local uInt longest_match(s, cur_match, clas)
+local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
- int clas;
{
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-#error "This code not patched"
-
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
@@ -1496,21 +1360,6 @@ local void fill_window(s)
*/
} while (--n);
#endif
-
- for (n = 0; n < Z_COOKIE_HASH_SIZE; n++) {
- if (s->cookie_locations[n] > wsize) {
- s->cookie_locations[n] -= wsize;
- } else {
- s->cookie_locations[n] = 0;
- }
- }
-
- if (s->class_bitmap) {
- zmemcpy(s->class_bitmap, s->class_bitmap + s->w_size/8,
- s->w_size/8);
- zmemzero(s->class_bitmap + s->w_size/8, s->w_size/8);
- }
-
more += wsize;
}
if (s->strm->avail_in == 0) return;
@@ -1529,9 +1378,6 @@ local void fill_window(s)
Assert(more >= 2, "more < 2");
n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- if (s->class_bitmap != NULL) {
- class_set(s, s->strstart + s->lookahead, n, s->strm->clas);
- }
s->lookahead += n;
/* Initialize the hash value now that we have some input: */
@@ -1613,10 +1459,9 @@ local void fill_window(s)
* NOTE: this function should be optimized to avoid extra copying from
* window to pending_buf.
*/
-local block_state deflate_stored(s, flush, clas)
+local block_state deflate_stored(s, flush)
deflate_state *s;
int flush;
- int clas;
{
/* Stored blocks are limited to 0xffff bytes, pending_buf is limited
* to pending_buf_size, and each stored block has a 5 byte header:
@@ -1672,19 +1517,13 @@ local block_state deflate_stored(s, flush, clas)
* new strings in the dictionary only for unmatched strings or for short
* matches. It is used only for the fast compression options.
*/
-local block_state deflate_fast(s, flush, clas)
+local block_state deflate_fast(s, flush)
deflate_state *s;
int flush;
- int clas;
{
IPos hash_head; /* head of the hash chain */
int bflush; /* set if current block must be flushed */
- if (clas != 0) {
- /* We haven't patched this code for alternative class data. */
- return Z_BUF_ERROR;
- }
-
for (;;) {
/* Make sure that we always have enough lookahead, except
* at the end of the input file. We need MAX_MATCH bytes
@@ -1715,7 +1554,7 @@ local block_state deflate_fast(s, flush, clas)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- s->match_length = longest_match (s, hash_head, clas);
+ s->match_length = longest_match (s, hash_head);
/* longest_match() sets match_start */
}
if (s->match_length >= MIN_MATCH) {
@@ -1774,25 +1613,12 @@ local block_state deflate_fast(s, flush, clas)
* evaluation for matches: a match is finally adopted only if there is
* no better match at the next window position.
*/
-local block_state deflate_slow(s, flush, clas)
+local block_state deflate_slow(s, flush)
deflate_state *s;
int flush;
- int clas;
{
IPos hash_head; /* head of hash chain */
int bflush; /* set if current block must be flushed */
- uInt input_length ;
- int first = 1; /* first says whether this is the first iteration
- of the loop, below. */
-
- if (clas == Z_CLASS_COOKIE) {
- if (s->lookahead) {
- /* Alternative class data must always be presented at the beginning
- * of a block. */
- return Z_BUF_ERROR;
- }
- input_length = s->strm->avail_in;
- }
/* Process the input block. */
for (;;) {
@@ -1822,18 +1648,13 @@ local block_state deflate_slow(s, flush, clas)
s->prev_length = s->match_length, s->prev_match = s->match_start;
s->match_length = MIN_MATCH-1;
- if (clas == Z_CLASS_COOKIE && first) {
- s->match_length = cookie_match(s, s->strstart, input_length);
- } else if (clas == Z_CLASS_STANDARD &&
- hash_head != NIL &&
- s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
/* To simplify the code, we prevent matches with the string
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
- s->match_length = longest_match (s, hash_head, clas);
-
+ s->match_length = longest_match (s, hash_head);
/* longest_match() sets match_start */
if (s->match_length <= 5 && (s->strategy == Z_FILTERED
@@ -1852,22 +1673,7 @@ local block_state deflate_slow(s, flush, clas)
/* If there was a match at the previous step and the current
* match is not better, output the previous match:
*/
- first = 0;
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length &&
- /* We will only accept an exact match for Z_CLASS_COOKIE data and
- * we won't match Z_CLASS_HUFFMAN_ONLY data at all. */
- (clas == Z_CLASS_STANDARD || (clas == Z_CLASS_COOKIE &&
- s->prev_length == input_length &&
- s->prev_match > 0 &&
- /* We require that a Z_CLASS_COOKIE match be
- * preceded by either a semicolon (which cannot be
- * part of a cookie), or non-cookie data. This is
- * to prevent
- * a cookie from being a prefix of another.
- * spdy_framer.cc ensures that cookies are always
- * terminated by a semicolon. */
- (class_at(s, s->prev_match-1) == Z_CLASS_STANDARD ||
- *(s->window + s->prev_match-1) == ';')))) {
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
/* Do not insert strings in hash table beyond this. */
diff --git a/third_party/zlib/deflate.h b/third_party/zlib/deflate.h
index 83b4602..cbf0d1e 100644
--- a/third_party/zlib/deflate.h
+++ b/third_party/zlib/deflate.h
@@ -91,9 +91,6 @@ typedef unsigned IPos;
* save space in the various tables. IPos is used only for parameter passing.
*/
-#define Z_COOKIE_HASH_SIZE 64
-#define Z_COOKIE_HASH_MASK (Z_COOKIE_HASH_SIZE-1)
-
typedef struct internal_state {
z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */
@@ -142,8 +139,6 @@ typedef struct internal_state {
uInt hash_mask; /* hash_size-1 */
uInt hash_shift;
- Bytef *class_bitmap; /* bitmap of class for each byte in window */
- IPos cookie_locations[Z_COOKIE_HASH_SIZE];
/* Number of bits by which ins_h must be shifted at each input
* step. It must be such that after MIN_MATCH steps, the oldest
* byte no longer takes part in the hash key, that is:
diff --git a/third_party/zlib/mixed-source.patch b/third_party/zlib/mixed-source.patch
deleted file mode 100644
index bd55ef4..0000000
--- a/third_party/zlib/mixed-source.patch
+++ /dev/null
@@ -1,491 +0,0 @@
-diff --git a/third_party/zlib/deflate.c b/third_party/zlib/deflate.c
-index 5c4022f..02d1516 100644
---- a/third_party/zlib/deflate.c
-+++ b/third_party/zlib/deflate.c
-@@ -70,14 +70,15 @@ typedef enum {
- finish_done /* finish done, accept no more input or output */
- } block_state;
-
--typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-+typedef block_state (*compress_func) OF((deflate_state *s, int flush,
-+ int clas));
- /* Compression function. Returns the block state after the call. */
-
- local void fill_window OF((deflate_state *s));
--local block_state deflate_stored OF((deflate_state *s, int flush));
--local block_state deflate_fast OF((deflate_state *s, int flush));
-+local block_state deflate_stored OF((deflate_state *s, int flush, int clas));
-+local block_state deflate_fast OF((deflate_state *s, int flush, int clas));
- #ifndef FASTEST
--local block_state deflate_slow OF((deflate_state *s, int flush));
-+local block_state deflate_slow OF((deflate_state *s, int flush, int clas));
- #endif
- local block_state deflate_rle OF((deflate_state *s, int flush));
- local block_state deflate_huff OF((deflate_state *s, int flush));
-@@ -87,9 +88,9 @@ local void flush_pending OF((z_streamp strm));
- local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
- #ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
-- uInt longest_match OF((deflate_state *s, IPos cur_match));
-+ uInt longest_match OF((deflate_state *s, IPos cur_match, int clas));
- #else
--local uInt longest_match OF((deflate_state *s, IPos cur_match));
-+local uInt longest_match OF((deflate_state *s, IPos cur_match, int clas));
- #endif
-
- #ifdef DEBUG
-@@ -281,6 +282,9 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-+ s->class_bitmap = NULL;
-+ zmemzero(&s->cookie_locations, sizeof(s->cookie_locations));
-+ strm->clas = 0;
-
- s->high_water = 0; /* nothing written to s->window yet */
-
-@@ -367,6 +371,8 @@ int ZEXPORT deflateReset (strm)
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-+ TRY_FREE(strm, s->class_bitmap);
-+ s->class_bitmap = NULL;
-
- if (s->wrap < 0) {
- s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
-@@ -817,9 +823,26 @@ int ZEXPORT deflate (strm, flush)
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
-- bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
-- (s->strategy == Z_RLE ? deflate_rle(s, flush) :
-- (*(configuration_table[s->level].func))(s, flush));
-+ if (strm->clas && s->class_bitmap == NULL) {
-+ /* This is the first time that we have seen alternative class
-+ * data. All data up till this point has been standard class. */
-+ s->class_bitmap = (Bytef*) ZALLOC(strm, s->w_size/4, sizeof(Byte));
-+ zmemzero(s->class_bitmap, s->w_size/4);
-+ }
-+
-+ if (strm->clas && s->strategy == Z_RLE) {
-+ /* We haven't patched deflate_rle. */
-+ ERR_RETURN(strm, Z_BUF_ERROR);
-+ }
-+
-+ if (s->strategy == Z_HUFFMAN_ONLY) {
-+ bstate = deflate_huff(s, flush);
-+ } else if (s->strategy == Z_RLE) {
-+ bstate = deflate_rle(s, flush);
-+ } else {
-+ bstate = (*(configuration_table[s->level].func))
-+ (s, flush, strm->clas);
-+ }
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
-@@ -915,6 +938,7 @@ int ZEXPORT deflateEnd (strm)
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-+ TRY_FREE(strm, strm->state->class_bitmap);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-@@ -1046,6 +1070,57 @@ local void lm_init (s)
- #endif
- }
-
-+/* class_set sets bits [offset,offset+len) in s->class_bitmap to either 1 (if
-+ * class != 0) or 0 (otherwise). */
-+local void class_set(s, offset, len, clas)
-+ deflate_state *s;
-+ IPos offset;
-+ uInt len;
-+ int clas;
-+{
-+ IPos byte = offset >> 3;
-+ IPos bit = offset & 7;
-+ Bytef class_byte_value = clas ? 0xff : 0x00;
-+ Bytef class_bit_value = clas ? 1 : 0;
-+ static const Bytef mask[8] = {0xfe, 0xfd, 0xfb, 0xf7,
-+ 0xef, 0xdf, 0xbf, 0x7f};
-+
-+ if (bit) {
-+ while (len) {
-+ s->class_bitmap[byte] &= mask[bit];
-+ s->class_bitmap[byte] |= class_bit_value << bit;
-+ bit++;
-+ len--;
-+ if (bit == 8) {
-+ bit = 0;
-+ byte++;
-+ break;
-+ }
-+ }
-+ }
-+
-+ while (len >= 8) {
-+ s->class_bitmap[byte++] = class_byte_value;
-+ len -= 8;
-+ }
-+
-+ while (len) {
-+ s->class_bitmap[byte] &= mask[bit];
-+ s->class_bitmap[byte] |= class_bit_value << bit;
-+ bit++;
-+ len--;
-+ }
-+}
-+
-+local int class_at(s, window_offset)
-+ deflate_state *s;
-+ IPos window_offset;
-+{
-+ IPos byte = window_offset >> 3;
-+ IPos bit = window_offset & 7;
-+ return (s->class_bitmap[byte] >> bit) & 1;
-+}
-+
- #ifndef FASTEST
- /* ===========================================================================
- * Set match_start to the longest match starting at the given string and
-@@ -1060,9 +1135,10 @@ local void lm_init (s)
- /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
--local uInt longest_match(s, cur_match)
-+local uInt longest_match(s, cur_match, clas)
- deflate_state *s;
- IPos cur_match; /* current match */
-+ int clas;
- {
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
-@@ -1110,6 +1186,9 @@ local uInt longest_match(s, cur_match)
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-+ /* If the matched data is in the wrong class, skip it. */
-+ if (s->class_bitmap && class_at(s, cur_match) != clas)
-+ continue;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2. Note that the checks below
-@@ -1152,6 +1231,8 @@ local uInt longest_match(s, cur_match)
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-+#error "UNALIGNED_OK hasn't been patched."
-+
- #else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
-@@ -1168,15 +1249,23 @@ local uInt longest_match(s, cur_match)
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
-- /* We check for insufficient lookahead only every 8th comparison;
-- * the 256th check will be made at strstart+258.
-- */
-- do {
-- } while (*++scan == *++match && *++scan == *++match &&
-- *++scan == *++match && *++scan == *++match &&
-- *++scan == *++match && *++scan == *++match &&
-- *++scan == *++match && *++scan == *++match &&
-- scan < strend);
-+ if (!s->class_bitmap) {
-+ /* We check for insufficient lookahead only every 8th comparison;
-+ * the 256th check will be made at strstart+258.
-+ */
-+ do {
-+ } while (*++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ scan < strend);
-+ } else {
-+ /* We have to be mindful of the class of the data and not stray. */
-+ do {
-+ } while (*++scan == *++match &&
-+ class_at(s, match - s->window) == clas &&
-+ scan < strend);
-+ }
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-@@ -1204,20 +1293,67 @@ local uInt longest_match(s, cur_match)
- }
- #endif /* ASMV */
-
-+/* cookie_match is a replacement for longest_match in the case of cookie data.
-+ * Here we only wish to match the entire value so trying the partial matches in
-+ * longest_match is both wasteful and often fails to find the correct match.
-+ *
-+ * So we take the djb2 hash of the cookie and look up the last position for a
-+ * match in a special hash table. */
-+local uInt cookie_match(s, start, len)
-+ deflate_state *s;
-+ IPos start;
-+ unsigned len;
-+{
-+ unsigned hash = 5381;
-+ Bytef *str = s->window + start;
-+ unsigned i;
-+ IPos cookie_location;
-+
-+ if (len >= MAX_MATCH)
-+ return 0;
-+
-+ for (i = 0; i < len; i++)
-+ hash = ((hash << 5) + hash) + str[i];
-+
-+ hash &= Z_COOKIE_HASH_MASK;
-+ cookie_location = s->cookie_locations[hash];
-+ s->cookie_locations[hash] = start;
-+ s->match_start = 0;
-+ if (cookie_location &&
-+ (start - cookie_location) > len &&
-+ (start - cookie_location) < MAX_DIST(s) &&
-+ len <= s->lookahead) {
-+ for (i = 0; i < len; i++) {
-+ if (s->window[start+i] != s->window[cookie_location+i] ||
-+ class_at(s, cookie_location+i) != 1) {
-+ return 0;
-+ }
-+ }
-+ s->match_start = cookie_location;
-+ return len;
-+ }
-+
-+ return 0;
-+}
-+
-+
- #else /* FASTEST */
-
- /* ---------------------------------------------------------------------------
- * Optimized version for FASTEST only
- */
--local uInt longest_match(s, cur_match)
-+local uInt longest_match(s, cur_match, clas)
- deflate_state *s;
- IPos cur_match; /* current match */
-+ int clas;
- {
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
-+#error "This code not patched"
-+
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
-@@ -1360,6 +1496,21 @@ local void fill_window(s)
- */
- } while (--n);
- #endif
-+
-+ for (n = 0; n < Z_COOKIE_HASH_SIZE; n++) {
-+ if (s->cookie_locations[n] > wsize) {
-+ s->cookie_locations[n] -= wsize;
-+ } else {
-+ s->cookie_locations[n] = 0;
-+ }
-+ }
-+
-+ if (s->class_bitmap) {
-+ zmemcpy(s->class_bitmap, s->class_bitmap + s->w_size/8,
-+ s->w_size/8);
-+ zmemzero(s->class_bitmap + s->w_size/8, s->w_size/8);
-+ }
-+
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-@@ -1378,6 +1529,9 @@ local void fill_window(s)
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
-+ if (s->class_bitmap != NULL) {
-+ class_set(s, s->strstart + s->lookahead, n, s->strm->clas);
-+ }
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
-@@ -1459,9 +1613,10 @@ local void fill_window(s)
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
--local block_state deflate_stored(s, flush)
-+local block_state deflate_stored(s, flush, clas)
- deflate_state *s;
- int flush;
-+ int clas;
- {
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
-@@ -1517,13 +1672,19 @@ local block_state deflate_stored(s, flush)
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
--local block_state deflate_fast(s, flush)
-+local block_state deflate_fast(s, flush, clas)
- deflate_state *s;
- int flush;
-+ int clas;
- {
- IPos hash_head; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
-+ if (clas != 0) {
-+ /* We haven't patched this code for alternative class data. */
-+ return Z_BUF_ERROR;
-+ }
-+
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
-@@ -1554,7 +1715,7 @@ local block_state deflate_fast(s, flush)
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
-- s->match_length = longest_match (s, hash_head);
-+ s->match_length = longest_match (s, hash_head, clas);
- /* longest_match() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
-@@ -1613,12 +1774,25 @@ local block_state deflate_fast(s, flush)
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
--local block_state deflate_slow(s, flush)
-+local block_state deflate_slow(s, flush, clas)
- deflate_state *s;
- int flush;
-+ int clas;
- {
- IPos hash_head; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-+ uInt input_length ;
-+ int first = 1; /* first says whether this is the first iteration
-+ of the loop, below. */
-+
-+ if (clas == Z_CLASS_COOKIE) {
-+ if (s->lookahead) {
-+ /* Alternative class data must always be presented at the beginning
-+ * of a block. */
-+ return Z_BUF_ERROR;
-+ }
-+ input_length = s->strm->avail_in;
-+ }
-
- /* Process the input block. */
- for (;;) {
-@@ -1648,13 +1822,18 @@ local block_state deflate_slow(s, flush)
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
-- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
-- s->strstart - hash_head <= MAX_DIST(s)) {
-+ if (clas == Z_CLASS_COOKIE && first) {
-+ s->match_length = cookie_match(s, s->strstart, input_length);
-+ } else if (clas == Z_CLASS_STANDARD &&
-+ hash_head != NIL &&
-+ s->prev_length < s->max_lazy_match &&
-+ s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
-- s->match_length = longest_match (s, hash_head);
-+ s->match_length = longest_match (s, hash_head, clas);
-+
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED
-@@ -1673,7 +1852,22 @@ local block_state deflate_slow(s, flush)
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
-- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
-+ first = 0;
-+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length &&
-+ /* We will only accept an exact match for Z_CLASS_COOKIE data and
-+ * we won't match Z_CLASS_HUFFMAN_ONLY data at all. */
-+ (clas == Z_CLASS_STANDARD || (clas == Z_CLASS_COOKIE &&
-+ s->prev_length == input_length &&
-+ s->prev_match > 0 &&
-+ /* We require that a Z_CLASS_COOKIE match be
-+ * preceded by either a semicolon (which cannot be
-+ * part of a cookie), or non-cookie data. This is
-+ * to prevent
-+ * a cookie from being a prefix of another.
-+ * spdy_framer.cc ensures that cookies are always
-+ * terminated by a semicolon. */
-+ (class_at(s, s->prev_match-1) == Z_CLASS_STANDARD ||
-+ *(s->window + s->prev_match-1) == ';')))) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
-diff --git a/third_party/zlib/deflate.h b/third_party/zlib/deflate.h
-index cbf0d1e..83b4602 100644
---- a/third_party/zlib/deflate.h
-+++ b/third_party/zlib/deflate.h
-@@ -91,6 +91,9 @@ typedef unsigned IPos;
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-+#define Z_COOKIE_HASH_SIZE 64
-+#define Z_COOKIE_HASH_MASK (Z_COOKIE_HASH_SIZE-1)
-+
- typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
-@@ -139,6 +142,8 @@ typedef struct internal_state {
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
-+ Bytef *class_bitmap; /* bitmap of class for each byte in window */
-+ IPos cookie_locations[Z_COOKIE_HASH_SIZE];
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
-diff --git a/third_party/zlib/zlib.h b/third_party/zlib/zlib.h
-index 4d54af9..da7e971 100644
---- a/third_party/zlib/zlib.h
-+++ b/third_party/zlib/zlib.h
-@@ -101,6 +101,7 @@ typedef struct z_stream_s {
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-+ int clas;
- } z_stream;
-
- typedef z_stream FAR *z_streamp;
-@@ -207,6 +208,10 @@ typedef gz_header FAR *gz_headerp;
-
- #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-+#define Z_CLASS_STANDARD 0
-+#define Z_CLASS_COOKIE 1
-+#define Z_CLASS_HUFFMAN_ONLY 2
-+
- #define zlib_version zlibVersion()
- /* for compatibility with versions < 1.0.2 */
-
-@@ -1587,6 +1592,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
- ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
- ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-+# else
-+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
-+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
-+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
-+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
-+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
-+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
- # endif
- #else
- ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
diff --git a/third_party/zlib/zlib.gyp b/third_party/zlib/zlib.gyp
index 73c4f43..4215f62 100644
--- a/third_party/zlib/zlib.gyp
+++ b/third_party/zlib/zlib.gyp
@@ -5,10 +5,12 @@
{
'variables': {
'conditions': [
- [ 'OS=="none"', {
- # Because we have a patched zlib, we cannot use the system libz.
+ [ 'os_posix == 1 and OS != "mac" and OS != "openbsd"', {
+ # Link to system .so since we already use it due to GTK.
+ # TODO(pvalchev): OpenBSD is purposefully left out, as the system
+ # zlib brings up an incompatibility that breaks rendering.
'use_system_zlib%': 1,
- }, {
+ }, { # os_posix != 1 or OS == "mac" or OS == "openbsd"
'use_system_zlib%': 0,
}],
],
@@ -68,8 +70,6 @@
'sources!': [
'contrib/minizip/iowin32.c'
],
- }], ['OS=="android"', {
- 'toolsets': ['target', 'host'],
}],
],
}, {
diff --git a/third_party/zlib/zlib.h b/third_party/zlib/zlib.h
index da7e971..4d54af9 100644
--- a/third_party/zlib/zlib.h
+++ b/third_party/zlib/zlib.h
@@ -101,7 +101,6 @@ typedef struct z_stream_s {
int data_type; /* best guess about the data type: binary or text */
uLong adler; /* adler32 value of the uncompressed data */
uLong reserved; /* reserved for future use */
- int clas;
} z_stream;
typedef z_stream FAR *z_streamp;
@@ -208,10 +207,6 @@ typedef gz_header FAR *gz_headerp;
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-#define Z_CLASS_STANDARD 0
-#define Z_CLASS_COOKIE 1
-#define Z_CLASS_HUFFMAN_ONLY 2
-
#define zlib_version zlibVersion()
/* for compatibility with versions < 1.0.2 */
@@ -1592,13 +1587,6 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
-# else
- ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
- ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
- ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
- ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
- ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
- ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
# endif
#else
ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));