From 03bc1c07f85e16fd32ee9e4bfec44998f44f998b Mon Sep 17 00:00:00 2001 From: "stoyan@chromium.org" Date: Thu, 8 Apr 2010 22:08:59 +0000 Subject: Fix horrible bug in Cache. Unittest added. Review URL: http://codereview.chromium.org/1611012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44011 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome_frame/test/url_request_test.cc | 72 +++++++++++++++++++++++++++++++++++ chrome_frame/urlmon_url_request.cc | 1 + 2 files changed, 73 insertions(+) diff --git a/chrome_frame/test/url_request_test.cc b/chrome_frame/test/url_request_test.cc index efdebc2..5be343f9 100644 --- a/chrome_frame/test/url_request_test.cc +++ b/chrome_frame/test/url_request_test.cc @@ -16,6 +16,78 @@ using testing::CreateFunctor; const int kChromeFrameLongNavigationTimeoutInSeconds = 10; +static void AppendToStream(IStream* s, void* buffer, ULONG cb) { + ULONG bytes_written; + LARGE_INTEGER current_pos; + LARGE_INTEGER zero = {0}; + // Remember current position. + ASSERT_HRESULT_SUCCEEDED(s->Seek(zero, STREAM_SEEK_CUR, + reinterpret_cast(¤t_pos))); + // Seek to the end. + ASSERT_HRESULT_SUCCEEDED(s->Seek(zero, STREAM_SEEK_END, NULL)); + ASSERT_HRESULT_SUCCEEDED(s->Write(buffer, cb, &bytes_written)); + ASSERT_EQ(cb, bytes_written); + // Seek to original position. + ASSERT_HRESULT_SUCCEEDED(s->Seek(current_pos, STREAM_SEEK_SET, NULL)); +} + +TEST(UrlmonUrlRequestCache, ReadWrite) { + UrlmonUrlRequest::Cache cache; + ScopedComPtr stream; + ASSERT_HRESULT_SUCCEEDED(::CreateStreamOnHGlobal(0, TRUE, stream.Receive())); + cache.Append(stream); + ASSERT_EQ(0, cache.size()); + size_t bytes_read; + const size_t BUF_SIZE = UrlmonUrlRequest::Cache::BUF_SIZE; + scoped_array buffer(new uint8[BUF_SIZE * 2]); + + AppendToStream(stream, "hello", 5u); + ASSERT_TRUE(cache.Append(stream)); + ASSERT_HRESULT_SUCCEEDED(cache.Read(buffer.get(), 2u, &bytes_read)); + ASSERT_EQ(2, bytes_read); + ASSERT_EQ('h', buffer[0]); + ASSERT_EQ('e', buffer[1]); + + AppendToStream(stream, "world\0", 6u); + ASSERT_TRUE(cache.Append(stream)); + ASSERT_HRESULT_SUCCEEDED(cache.Read(buffer.get(), 1u, &bytes_read)); + ASSERT_EQ(1, bytes_read); + ASSERT_EQ('l', buffer[0]); + ASSERT_HRESULT_SUCCEEDED(cache.Read(buffer.get(), 100u, &bytes_read)); + ASSERT_EQ(8, bytes_read); + ASSERT_STREQ("loworld", (const char*)buffer.get()); + + memset(buffer.get(), '1', BUF_SIZE / 2); + AppendToStream(stream, buffer.get(), BUF_SIZE / 2); + cache.Append(stream); + memset(buffer.get(), '2', BUF_SIZE); + AppendToStream(stream, buffer.get(), BUF_SIZE); + memset(buffer.get(), '3', BUF_SIZE * 3 / 4); + AppendToStream(stream, buffer.get(), BUF_SIZE * 3 / 4); + cache.Append(stream); + + cache.Read(buffer.get(), BUF_SIZE / 2, &bytes_read); + ASSERT_EQ(BUF_SIZE / 2, bytes_read); + ASSERT_EQ('1', buffer[0]); + ASSERT_EQ('1', buffer[BUF_SIZE / 4]); + ASSERT_EQ('1', buffer[BUF_SIZE /2 - 1]); + + cache.Read(buffer.get(), BUF_SIZE, &bytes_read); + ASSERT_EQ(BUF_SIZE, bytes_read); + ASSERT_EQ('2', buffer[0]); + ASSERT_EQ('2', buffer[BUF_SIZE /2]); + ASSERT_EQ('2', buffer[BUF_SIZE - 1]); + + cache.Read(buffer.get(), BUF_SIZE * 3 / 4, &bytes_read); + ASSERT_EQ(BUF_SIZE * 3 / 4, bytes_read); + ASSERT_EQ('3', buffer[0]); + ASSERT_EQ('3', buffer[BUF_SIZE / 2]); + ASSERT_EQ('3', buffer[BUF_SIZE * 3 / 4 - 1]); + cache.Read(buffer.get(), 11, &bytes_read); + ASSERT_EQ(0, bytes_read); +} + + class MockUrlDelegate : public PluginUrlRequestDelegate { public: MOCK_METHOD7(OnResponseStarted, void(int request_id, const char* mime_type, diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc index 783fcf0..c2ac15d 100644 --- a/chrome_frame/urlmon_url_request.cc +++ b/chrome_frame/urlmon_url_request.cc @@ -822,6 +822,7 @@ bool UrlmonUrlRequest::Cache::Read(void* dest, size_t bytes, memcpy(dest, src, bytes_to_copy); BytesRead(bytes_to_copy); + dest = reinterpret_cast(dest) + bytes_to_copy; bytes -= bytes_to_copy; *bytes_copied += bytes_to_copy; } -- cgit v1.1