Skip to content

Commit 2b42028

Browse files
[WPE] Increased memory consumption of WebProcess during regular video playback and RWI
https://bugs.webkit.org/show_bug.cgi?id=284108 Reviewed by Devin Rousso. When WebInspector is used, the downloaded data is cached also for it in NetworkResourcesData. The single resource data cannot be greater than maximumSingleResourceContentSize (50MB) and the total size of resources content cannot be greater than maximumResourcesContentSize (200MB). At the end of downloading the resource, the binary data is decoded to the string represantation (base64 or other depends on decoder). Decoding process can increased the size of the kept resource data. The limit maximumSingleResourceContentSize is checked but maximumResourcesContentSize limit is not checked which can lead to situation that m_contentSize (the total size of resources content) is greater than maximumResourcesContentSize. This causes that condition checked in NetworkResourcesData::ensureFreeSpace is invalid because subtraction unsigned values where first value(minuend) is smaller than the second one(subtrahend) gives a huge number (instead of negative number). This change ensures that after decoding binary data into string representation the total size of resources content (m_contentSize) is not greater than maximumResourcesContentSize. The assert is added in NetworkResourcesData::ensureFreeSpace to check that m_contentSize is not greater than maximumResourcesContentSize. I fixed implementation of function NetworkResourcesData::clear in case passing the preservedLoaderId. In that case we should update m_requestIdsDeque and m_contentSize and not just clear them. Additionally I changed the type of m_requestIdsDeque from Deque<String> to ListHashSet<String>. This change fixes adding to m_requestIdsDeque the same requestId many times. * Source/WebCore/inspector/NetworkResourcesData.cpp: (WebCore::NetworkResourcesData::ResourceData::decodeDataToContent): (WebCore::NetworkResourcesData::setResourceContent): (WebCore::NetworkResourcesData::maybeAddResourceData): (WebCore::NetworkResourcesData::maybeDecodeDataToContent): (WebCore::NetworkResourcesData::clear): (WebCore::NetworkResourcesData::ensureFreeSpace): * Source/WebCore/inspector/NetworkResourcesData.h: Canonical link: https://commits.webkit.org/289143@main
1 parent f9ed45c commit 2b42028

2 files changed

Lines changed: 35 additions & 22 deletions

File tree

Source/WebCore/inspector/NetworkResourcesData.cpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void NetworkResourcesData::ResourceData::appendData(const SharedBuffer& data)
9696
m_dataBuffer.append(data);
9797
}
9898

99-
unsigned NetworkResourcesData::ResourceData::decodeDataToContent()
99+
void NetworkResourcesData::ResourceData::decodeDataToContent()
100100
{
101101
ASSERT(!hasContent());
102102

@@ -111,7 +111,7 @@ unsigned NetworkResourcesData::ResourceData::decodeDataToContent()
111111
m_content = base64EncodeToString(buffer->data(), dataLength);
112112
}
113113

114-
return m_content.sizeInBytes() - dataLength;
114+
ASSERT(m_content.sizeInBytes() >= buffer->size());
115115
}
116116

117117
NetworkResourcesData::NetworkResourcesData()
@@ -200,7 +200,7 @@ void NetworkResourcesData::setResourceContent(const String& requestId, const Str
200200
// We can not be sure that we didn't try to save this request data while it was loading, so remove it, if any.
201201
if (resourceData->hasContent() || resourceData->hasData())
202202
m_contentSize -= resourceData->removeContent();
203-
m_requestIdsDeque.append(requestId);
203+
m_requestIdsDeque.appendOrMoveToLast(requestId);
204204
resourceData->setContent(content, base64Encoded);
205205
m_contentSize += dataLength;
206206
}
@@ -236,7 +236,7 @@ NetworkResourcesData::ResourceData const* NetworkResourcesData::maybeAddResource
236236
return resourceData;
237237

238238
if (ensureFreeSpace(data.size()) && !resourceData->isContentEvicted()) {
239-
m_requestIdsDeque.append(requestId);
239+
m_requestIdsDeque.appendOrMoveToLast(requestId);
240240
resourceData->appendData(data);
241241
m_contentSize += data.size();
242242
}
@@ -253,10 +253,18 @@ void NetworkResourcesData::maybeDecodeDataToContent(const String& requestId)
253253
if (!resourceData->hasData())
254254
return;
255255

256-
m_contentSize += resourceData->decodeDataToContent();
257-
size_t dataLength = resourceData->content().sizeInBytes();
258-
if (dataLength > m_maximumSingleResourceContentSize)
259-
m_contentSize -= resourceData->evictContent();
256+
auto byteCount = resourceData->dataLength();
257+
m_contentSize -= byteCount;
258+
259+
resourceData->decodeDataToContent();
260+
byteCount = resourceData->content().sizeInBytes();
261+
if (byteCount > m_maximumSingleResourceContentSize) {
262+
resourceData->evictContent();
263+
return;
264+
}
265+
266+
if (ensureFreeSpace(byteCount) && !resourceData->isContentEvicted())
267+
m_contentSize += byteCount;
260268
}
261269

262270
void NetworkResourcesData::addCachedResource(const String& requestId, CachedResource* cachedResource)
@@ -313,19 +321,23 @@ Vector<String> NetworkResourcesData::removeCachedResource(CachedResource* cached
313321

314322
void NetworkResourcesData::clear(std::optional<String> preservedLoaderId)
315323
{
316-
m_requestIdsDeque.clear();
317-
m_contentSize = 0;
318-
319-
if (!preservedLoaderId)
324+
if (!preservedLoaderId) {
320325
m_requestIdToResourceDataMap.clear();
321-
else {
322-
Vector<String> keysToRemove;
323-
for (auto& [key, value] : m_requestIdToResourceDataMap) {
324-
if (value->loaderId() != *preservedLoaderId)
325-
keysToRemove.append(key);
326+
m_requestIdsDeque.clear();
327+
m_contentSize = 0;
328+
return;
329+
}
330+
331+
for (auto&& requestId : std::exchange(m_requestIdsDeque, { })) {
332+
auto resourceData = resourceDataForRequestId(requestId);
333+
if (!resourceData)
334+
continue;
335+
if (resourceData->loaderId() == *preservedLoaderId)
336+
m_requestIdsDeque.add(requestId);
337+
else {
338+
m_contentSize -= resourceData->evictContent();
339+
m_requestIdToResourceDataMap.remove(requestId);
326340
}
327-
for (auto& keyToRemove : keysToRemove)
328-
m_requestIdToResourceDataMap.remove(keyToRemove);
329341
}
330342
}
331343

@@ -357,6 +369,7 @@ bool NetworkResourcesData::ensureFreeSpace(size_t size)
357369
if (size > m_maximumResourcesContentSize)
358370
return false;
359371

372+
ASSERT(m_maximumResourcesContentSize >= m_contentSize);
360373
while (size > m_maximumResourcesContentSize - m_contentSize) {
361374
String requestId = m_requestIdsDeque.takeFirst();
362375
ResourceData* resourceData = resourceDataForRequestId(requestId);

Source/WebCore/inspector/NetworkResourcesData.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
#include "InspectorPageAgent.h"
3333
#include "SharedBuffer.h"
34-
#include <wtf/Deque.h>
34+
#include <wtf/ListHashSet.h>
3535
#include <wtf/RobinHoodHashMap.h>
3636
#include <wtf/WallTime.h>
3737
#include <wtf/text/WTFString.h>
@@ -109,7 +109,7 @@ class NetworkResourcesData {
109109
bool hasData() const;
110110
size_t dataLength() const;
111111
void appendData(const SharedBuffer&);
112-
unsigned decodeDataToContent();
112+
void decodeDataToContent();
113113

114114
String m_requestId;
115115
String m_loaderId;
@@ -156,7 +156,7 @@ class NetworkResourcesData {
156156
void ensureNoDataForRequestId(const String& requestId);
157157
bool ensureFreeSpace(size_t);
158158

159-
Deque<String> m_requestIdsDeque;
159+
ListHashSet<String> m_requestIdsDeque;
160160
MemoryCompactRobinHoodHashMap<String, std::unique_ptr<ResourceData>> m_requestIdToResourceDataMap;
161161
size_t m_contentSize { 0 };
162162
size_t m_maximumResourcesContentSize;

0 commit comments

Comments
 (0)