Commit 3c5a24bb authored by japhet's avatar japhet Committed by Commit bot

Don't leave a discarded SharedBuffer on Resource

If a SharedBuffer was unlocked and the OS then purged the
backing DiscardableMemory, we will evict the Resource from
MemoryCache. However, before doing so, we will give inspector
a chance to copy the data. In the case where the buffer was
purged, InspectorPageAgent may improperly handle the buffer
given its state. In that case, clear the buffer so there is
no opportunity for the inspector to misuse it.

BUG=594117
TEST=ResourceTest.LockFailureNoCrash

Review URL: https://codereview.chromium.org/1802313003

Cr-Commit-Position: refs/heads/master@{#381732}
parent 303fdfed
......@@ -890,6 +890,8 @@ bool Resource::lock()
// If locking fails, our buffer has been purged. There's no point
// in leaving a purged resource in MemoryCache.
if (!m_data->lock()) {
m_data.clear();
setEncodedSize(0);
memoryCache()->remove(this);
return false;
}
......
......@@ -4,6 +4,8 @@
#include "core/fetch/Resource.h"
#include "core/fetch/MemoryCache.h"
#include "platform/SharedBuffer.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
#include "platform/testing/TestingPlatformSupport.h"
......@@ -16,6 +18,22 @@ namespace blink {
namespace {
class UnlockableResource : public Resource {
public:
static RefPtrWillBeRawPtr<UnlockableResource> create(const KURL& url)
{
return adoptRefWillBeNoop(new UnlockableResource(ResourceRequest(url), Resource::Raw));
}
private:
UnlockableResource(const ResourceRequest& request, Type type)
: Resource(request, type)
{
}
bool isSafeToUnlock() const override { return true; }
};
class MockPlatform final : public TestingPlatformSupport {
public:
MockPlatform() { }
......@@ -72,4 +90,27 @@ TEST(ResourceTest, SetCachedMetadata_DoesNotSendMetadataToPlatformWhenFetchedVia
EXPECT_EQ(0u, mock.cachedURLs().size());
}
TEST(ResourceTest, LockFailureNoCrash)
{
ResourceResponse response(createTestResourceResponse());
RefPtrWillBeRawPtr<UnlockableResource> resource = UnlockableResource::create(response.url());
memoryCache()->add(resource.get());
resource->setResponse(response);
// A Resource won't be put in DiscardableMemory unless it is at least 16KiB.
Vector<char> dataVector(4*4096);
for (int i = 0; i < 4096; i++)
dataVector.append("test", 4);
resource->setResourceBuffer(SharedBuffer::adoptVector(dataVector));
resource->setLoadFinishTime(currentTime());
resource->finish();
resource->prune();
ASSERT_TRUE(resource->isPurgeable());
bool didLock = resource->lock();
ASSERT_FALSE(didLock);
EXPECT_EQ(nullptr, resource->resourceBuffer());
EXPECT_EQ(size_t(0), resource->encodedSize());
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment