1 /* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "modules/websockets/WebSocketDeflater.h" 28 29 #include "wtf/Vector.h" 30 #include <gtest/gtest.h> 31 32 using namespace WebCore; 33 34 namespace { 35 36 TEST(WebSocketDeflaterTest, TestCompressHello) 37 { 38 // Test the first example on section 4.3 of the specification. 39 OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15); 40 ASSERT_TRUE(deflater->initialize()); 41 OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create(); 42 ASSERT_TRUE(inflater->initialize()); 43 const char* inputData = "Hello"; 44 const size_t inputLength = strlen(inputData); 45 46 ASSERT_TRUE(deflater->addBytes(inputData, inputLength)); 47 ASSERT_TRUE(deflater->finish()); 48 const char* expectedFirst = "\xf2\x48\xcd\xc9\xc9\x07\x00"; 49 EXPECT_EQ(7U, deflater->size()); 50 EXPECT_EQ(0, memcmp(expectedFirst, deflater->data(), deflater->size())); 51 ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size())); 52 ASSERT_TRUE(inflater->finish()); 53 EXPECT_EQ(inputLength, inflater->size()); 54 EXPECT_EQ(0, memcmp(inputData, inflater->data(), inflater->size())); 55 56 deflater->reset(); 57 inflater->reset(); 58 59 ASSERT_TRUE(deflater->addBytes(inputData, inputLength)); 60 ASSERT_TRUE(deflater->finish()); 61 const char* expectedSecond = "\xf2\x00\x11\x00\x00"; 62 EXPECT_EQ(5U, deflater->size()); 63 EXPECT_EQ(0, memcmp(expectedSecond, deflater->data(), deflater->size())); 64 ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size())); 65 ASSERT_TRUE(inflater->finish()); 66 EXPECT_EQ(inputLength, inflater->size()); 67 EXPECT_EQ(0, memcmp(inputData, inflater->data(), inflater->size())); 68 } 69 70 TEST(WebSocketDeflaterTest, TestMultipleAddBytesCalls) 71 { 72 OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15); 73 ASSERT_TRUE(deflater->initialize()); 74 OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create(); 75 ASSERT_TRUE(inflater->initialize()); 76 Vector<char> inputData(32); 77 inputData.fill('a'); 78 79 for (size_t i = 0; i < inputData.size(); ++i) 80 ASSERT_TRUE(deflater->addBytes(inputData.data() + i, 1)); 81 ASSERT_TRUE(deflater->finish()); 82 for (size_t i = 0; i < deflater->size(); ++i) 83 ASSERT_TRUE(inflater->addBytes(deflater->data() + i, 1)); 84 ASSERT_TRUE(inflater->finish()); 85 EXPECT_EQ(inputData.size(), inflater->size()); 86 EXPECT_EQ(0, memcmp(inputData.data(), inflater->data(), inflater->size())); 87 } 88 89 TEST(WebSocketDeflaterTest, TestNoContextTakeOver) 90 { 91 OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15, WebSocketDeflater::DoNotTakeOverContext); 92 ASSERT_TRUE(deflater->initialize()); 93 OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create(); 94 ASSERT_TRUE(inflater->initialize()); 95 const char* expected = "\xf2\x48\xcd\xc9\xc9\x07\x00"; 96 const char* inputData = "Hello"; 97 const size_t inputLength = strlen(inputData); 98 99 // If we don't take over context, the second result should be the identical 100 // with the first one. 101 for (size_t i = 0; i < 2; ++i) { 102 ASSERT_TRUE(deflater->addBytes(inputData, inputLength)); 103 ASSERT_TRUE(deflater->finish()); 104 EXPECT_EQ(7U, deflater->size()); 105 EXPECT_EQ(0, memcmp(expected, deflater->data(), deflater->size())); 106 ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size())); 107 ASSERT_TRUE(inflater->finish()); 108 EXPECT_EQ(inputLength, inflater->size()); 109 EXPECT_EQ(0, memcmp(inputData, inflater->data(), inflater->size())); 110 deflater->reset(); 111 inflater->reset(); 112 } 113 } 114 115 TEST(WebSocketDeflaterTest, TestWindowBits) 116 { 117 Vector<char> inputData(1024 + 64 * 2); 118 inputData.fill('a'); 119 // Modify the head and tail of the inputData so that back-reference 120 // can be used if the window size is sufficiently-large. 121 for (size_t j = 0; j < 64; ++j) { 122 inputData[j] = 'b'; 123 inputData[inputData.size() - j - 1] = 'b'; 124 } 125 126 OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(8); 127 ASSERT_TRUE(deflater->initialize()); 128 ASSERT_TRUE(deflater->addBytes(inputData.data(), inputData.size())); 129 ASSERT_TRUE(deflater->finish()); 130 131 OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create(8); 132 ASSERT_TRUE(inflater->initialize()); 133 ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size())); 134 ASSERT_TRUE(inflater->finish()); 135 EXPECT_EQ(inputData.size(), inflater->size()); 136 EXPECT_EQ(0, memcmp(inputData.data(), inflater->data(), inflater->size())); 137 } 138 139 TEST(WebSocketDeflaterTest, TestLargeData) 140 { 141 OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15); 142 ASSERT_TRUE(deflater->initialize()); 143 OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create(); 144 ASSERT_TRUE(inflater->initialize()); 145 Vector<char> inputData(16 * 1024 * 1024); 146 inputData.fill('a'); 147 148 ASSERT_TRUE(deflater->addBytes(inputData.data(), inputData.size())); 149 ASSERT_TRUE(deflater->finish()); 150 ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size())); 151 ASSERT_TRUE(inflater->finish()); 152 EXPECT_EQ(inputData.size(), inflater->size()); 153 EXPECT_EQ(0, memcmp(inputData.data(), inflater->data(), inflater->size())); 154 } 155 156 } 157