Skip to content

Commit dd775c7

Browse files
committed
Crash in CachedResourceStreamingClient::dataReceived https://bugs.webkit.org/show_bug.cgi?id=266973
Reviewed by Michael Catanzaro, Carlos Garcia Campos and Xabier Rodriguez-Calvar. Store the WebKitWebSrc pointer as a weak reference in the CachedResourceStreamingClient. Using a const raw pointer was not sufficient, because nothing prevented other code to dispose the element, thus making the pointer point to garbage. We can't use a strong reference because it would introduce a reference cycle between WebKitWebSrc and the CachedResourceStreamingClient. * Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp: (webKitWebSrcMakeRequest): (CachedResourceStreamingClient::CachedResourceStreamingClient): (CachedResourceStreamingClient::~CachedResourceStreamingClient): (CachedResourceStreamingClient::checkUpdateBlocksize): (CachedResourceStreamingClient::responseReceived): (CachedResourceStreamingClient::dataReceived): (CachedResourceStreamingClient::accessControlCheckFailed): (CachedResourceStreamingClient::loadFailed): (CachedResourceStreamingClient::loadFinished): Canonical link: https://commits.webkit.org/272807@main Signed-off-by: GlebNovodranPE <gnovodran@productengine.com>
1 parent b7b5193 commit dd775c7

1 file changed

Lines changed: 55 additions & 34 deletions

File tree

Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <wtf/PrintStream.h>
3939
#include <wtf/RunLoop.h>
4040
#include <wtf/Scope.h>
41+
#include <wtf/glib/GThreadSafeWeakPtr.h>
4142
#include <wtf/glib/WTFGType.h>
4243
#include <wtf/text/CString.h>
4344
#include <wtf/text/StringToIntegerConversion.h>
@@ -59,7 +60,7 @@ class CachedResourceStreamingClient final : public PlatformMediaResourceClient {
5960
WTF_MAKE_FAST_ALLOCATED;
6061
WTF_MAKE_NONCOPYABLE(CachedResourceStreamingClient);
6162
public:
62-
CachedResourceStreamingClient(const WebKitWebSrc&, ResourceRequest&&, unsigned requestNumber);
63+
CachedResourceStreamingClient(WebKitWebSrc*, ResourceRequest&&, unsigned requestNumber);
6364
virtual ~CachedResourceStreamingClient();
6465

6566
const HashSet<RefPtr<WebCore::SecurityOrigin>>& securityOrigins() const { return m_origins; }
@@ -84,7 +85,7 @@ class CachedResourceStreamingClient final : public PlatformMediaResourceClient {
8485
int m_increaseBlocksizeCount { 0 };
8586
unsigned m_requestNumber;
8687

87-
const GstElement* m_src;
88+
GThreadSafeWeakPtr<WebKitWebSrc> m_src;
8889
ResourceRequest m_request;
8990
HashSet<RefPtr<WebCore::SecurityOrigin>> m_origins;
9091
};
@@ -708,7 +709,7 @@ static void webKitWebSrcMakeRequest(WebKitWebSrc* src, DataMutexLocker<WebKitWeb
708709
PlatformMediaResourceLoader::LoadOptions loadOptions = 0;
709710
members->resource = members->loader->requestResource(ResourceRequest(request), loadOptions);
710711
if (members->resource) {
711-
members->resource->setClient(adoptRef(*new CachedResourceStreamingClient(*protector.get(), ResourceRequest(request), requestNumber)));
712+
members->resource->setClient(adoptRef(*new CachedResourceStreamingClient(protector.get(), ResourceRequest(request), requestNumber)));
712713
GST_DEBUG_OBJECT(protector.get(), "Started request R%u", requestNumber);
713714
} else {
714715
GST_ERROR_OBJECT(protector.get(), "Failed to setup streaming client to handle R%u", requestNumber);
@@ -941,9 +942,9 @@ bool webKitSrcPassedCORSAccessCheck(WebKitWebSrc* src)
941942
return members->didPassAccessControlCheck;
942943
}
943944

944-
CachedResourceStreamingClient::CachedResourceStreamingClient(const WebKitWebSrc& src, ResourceRequest&& request, unsigned requestNumber)
945+
CachedResourceStreamingClient::CachedResourceStreamingClient(WebKitWebSrc* src, ResourceRequest&& request, unsigned requestNumber)
945946
: m_requestNumber(requestNumber)
946-
, m_src(GST_ELEMENT_CAST(&src))
947+
, m_src(src)
947948
, m_request(WTFMove(request))
948949
{
949950
}
@@ -953,20 +954,23 @@ CachedResourceStreamingClient::~CachedResourceStreamingClient() = default;
953954
void CachedResourceStreamingClient::checkUpdateBlocksize(unsigned bytesRead)
954955
{
955956
ASSERT(isMainThread());
956-
WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
957-
GstBaseSrc* baseSrc = GST_BASE_SRC_CAST(src);
957+
auto src = m_src.get();
958+
if (!src)
959+
return;
960+
961+
GstBaseSrc* baseSrc = GST_BASE_SRC_CAST(src.get());
958962
WebKitWebSrcPrivate* priv = src->priv;
959963

960964
unsigned blocksize = gst_base_src_get_blocksize(baseSrc);
961-
GST_LOG_OBJECT(src, "Checking to update blocksize. Read: %u, current blocksize: %u", bytesRead, blocksize);
965+
GST_LOG_OBJECT(src.get(), "Checking to update blocksize. Read: %u, current blocksize: %u", bytesRead, blocksize);
962966

963967
if (bytesRead > blocksize * s_growBlocksizeLimit) {
964968
m_reduceBlocksizeCount = 0;
965969
m_increaseBlocksizeCount++;
966970

967971
if (m_increaseBlocksizeCount >= s_growBlocksizeCount) {
968972
blocksize *= s_growBlocksizeFactor;
969-
GST_DEBUG_OBJECT(src, "Increased blocksize to %u", blocksize);
973+
GST_DEBUG_OBJECT(src.get(), "Increased blocksize to %u", blocksize);
970974
gst_base_src_set_blocksize(baseSrc, blocksize);
971975
m_increaseBlocksizeCount = 0;
972976
}
@@ -977,7 +981,7 @@ void CachedResourceStreamingClient::checkUpdateBlocksize(unsigned bytesRead)
977981
if (m_reduceBlocksizeCount >= s_reduceBlocksizeCount) {
978982
blocksize *= s_reduceBlocksizeFactor;
979983
blocksize = std::max(blocksize, priv->minimumBlocksize);
980-
GST_DEBUG_OBJECT(src, "Decreased blocksize to %u", blocksize);
984+
GST_DEBUG_OBJECT(src.get(), "Decreased blocksize to %u", blocksize);
981985
gst_base_src_set_blocksize(baseSrc, blocksize);
982986
m_reduceBlocksizeCount = 0;
983987
}
@@ -990,15 +994,20 @@ void CachedResourceStreamingClient::checkUpdateBlocksize(unsigned bytesRead)
990994
void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, const ResourceResponse& response, CompletionHandler<void(ShouldContinuePolicyCheck)>&& completionHandler)
991995
{
992996
ASSERT(isMainThread());
993-
WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
997+
auto src = m_src.get();
998+
if (!src) {
999+
completionHandler(ShouldContinuePolicyCheck::No);
1000+
return;
1001+
}
1002+
9941003
WebKitWebSrcPrivate* priv = src->priv;
9951004
DataMutexLocker members { priv->dataMutex };
9961005
if (members->requestNumber != m_requestNumber) {
9971006
completionHandler(ShouldContinuePolicyCheck::No);
9981007
return;
9991008
}
10001009

1001-
GST_DEBUG_OBJECT(src, "R%u: Received response: %d", m_requestNumber, response.httpStatusCode());
1010+
GST_DEBUG_OBJECT(src.get(), "R%u: Received response: %d", m_requestNumber, response.httpStatusCode());
10021011

10031012
members->didPassAccessControlCheck = members->resource->didPassAccessControlCheck();
10041013
m_origins.add(SecurityOrigin::create(response.url()));
@@ -1032,7 +1041,7 @@ void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, con
10321041
GUniquePtr<GstStructure> headers(gst_structure_new_empty("request-headers"));
10331042
for (const auto& header : m_request.httpHeaderFields())
10341043
gst_structure_set(headers.get(), header.key.utf8().data(), G_TYPE_STRING, header.value.utf8().data(), nullptr);
1035-
GST_DEBUG_OBJECT(src, "R%u: Request headers going downstream: %" GST_PTR_FORMAT, m_requestNumber, headers.get());
1044+
GST_DEBUG_OBJECT(src.get(), "R%u: Request headers going downstream: %" GST_PTR_FORMAT, m_requestNumber, headers.get());
10361045
gst_structure_set(httpHeaders.get(), "request-headers", GST_TYPE_STRUCTURE, headers.get(), nullptr);
10371046

10381047
// Pack response headers in the http-headers structure.
@@ -1043,14 +1052,14 @@ void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, con
10431052
else
10441053
gst_structure_set(headers.get(), header.key.utf8().data(), G_TYPE_STRING, header.value.utf8().data(), nullptr);
10451054
}
1046-
GST_DEBUG_OBJECT(src, "R%u: Response headers going downstream: %" GST_PTR_FORMAT, m_requestNumber, headers.get());
1055+
GST_DEBUG_OBJECT(src.get(), "R%u: Response headers going downstream: %" GST_PTR_FORMAT, m_requestNumber, headers.get());
10471056
gst_structure_set(httpHeaders.get(), "response-headers", GST_TYPE_STRUCTURE, headers.get(), nullptr);
10481057

1049-
members->pendingHttpHeadersMessage = adoptGRef(gst_message_new_element(GST_OBJECT_CAST(src), gst_structure_copy(httpHeaders.get())));
1058+
members->pendingHttpHeadersMessage = adoptGRef(gst_message_new_element(GST_OBJECT_CAST(src.get()), gst_structure_copy(httpHeaders.get())));
10501059
members->pendingHttpHeadersEvent = adoptGRef(gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, httpHeaders.release()));
10511060

10521061
if (response.httpStatusCode() >= 400) {
1053-
GST_ELEMENT_ERROR(src, RESOURCE, READ, ("R%u: Received %d HTTP error code", m_requestNumber, response.httpStatusCode()), (nullptr));
1062+
GST_ELEMENT_ERROR(src.get(), RESOURCE, READ, ("R%u: Received %d HTTP error code", m_requestNumber, response.httpStatusCode()), (nullptr));
10541063
members->doesHaveEOS = true;
10551064
members->responseCondition.notifyOne();
10561065
completionHandler(ShouldContinuePolicyCheck::No);
@@ -1061,18 +1070,18 @@ void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, con
10611070
// Seeking ... we expect a 206 == PARTIAL_CONTENT
10621071
if (response.httpStatusCode() != 206) {
10631072
// Range request completely failed.
1064-
GST_ELEMENT_ERROR(src, RESOURCE, READ, ("R%u: Received unexpected %d HTTP status code for range request", m_requestNumber, response.httpStatusCode()), (nullptr));
1073+
GST_ELEMENT_ERROR(src.get(), RESOURCE, READ, ("R%u: Received unexpected %d HTTP status code for range request", m_requestNumber, response.httpStatusCode()), (nullptr));
10651074
members->doesHaveEOS = true;
10661075
members->responseCondition.notifyOne();
10671076
completionHandler(ShouldContinuePolicyCheck::No);
10681077
return;
10691078
}
1070-
GST_DEBUG_OBJECT(src, "R%u: Range request succeeded", m_requestNumber);
1079+
GST_DEBUG_OBJECT(src.get(), "R%u: Range request succeeded", m_requestNumber);
10711080
}
10721081

10731082
members->isSeekable = length > 0 && g_ascii_strcasecmp("none", response.httpHeaderField(HTTPHeaderName::AcceptRanges).utf8().data());
10741083

1075-
GST_DEBUG_OBJECT(src, "R%u: Size: %" G_GUINT64_FORMAT ", isSeekable: %s", m_requestNumber, length, boolForPrinting(members->isSeekable));
1084+
GST_DEBUG_OBJECT(src.get(), "R%u: Size: %" G_GUINT64_FORMAT ", isSeekable: %s", m_requestNumber, length, boolForPrinting(members->isSeekable));
10761085
if (length > 0) {
10771086
if (!members->haveSize || members->size != length) {
10781087
members->haveSize = true;
@@ -1087,11 +1096,11 @@ void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, con
10871096
caps = adoptGRef(gst_caps_new_simple("application/x-icy", "metadata-interval", G_TYPE_INT, *metadataInterval, nullptr));
10881097

10891098
String contentType = response.httpHeaderField(HTTPHeaderName::ContentType);
1090-
GST_DEBUG_OBJECT(src, "R%u: Response ContentType: %s", m_requestNumber, contentType.utf8().data());
1099+
GST_DEBUG_OBJECT(src.get(), "R%u: Response ContentType: %s", m_requestNumber, contentType.utf8().data());
10911100
gst_caps_set_simple(caps.get(), "content-type", G_TYPE_STRING, contentType.utf8().data(), nullptr);
10921101
}
10931102
if (caps) {
1094-
GST_DEBUG_OBJECT(src, "R%u: Set caps to %" GST_PTR_FORMAT, m_requestNumber, caps.get());
1103+
GST_DEBUG_OBJECT(src.get(), "R%u: Set caps to %" GST_PTR_FORMAT, m_requestNumber, caps.get());
10951104
members->pendingCaps = WTFMove(caps);
10961105
}
10971106

@@ -1104,7 +1113,10 @@ void CachedResourceStreamingClient::responseReceived(PlatformMediaResource&, con
11041113
void CachedResourceStreamingClient::dataReceived(PlatformMediaResource&, const SharedBuffer& data)
11051114
{
11061115
ASSERT(isMainThread());
1107-
WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
1116+
auto src = m_src.get();
1117+
if (!src)
1118+
return;
1119+
11081120
WebKitWebSrcPrivate* priv = src->priv;
11091121

11101122
DataMutexLocker members { priv->dataMutex };
@@ -1117,55 +1129,61 @@ void CachedResourceStreamingClient::dataReceived(PlatformMediaResource&, const S
11171129
if (!std::isnan(members->downloadStartTime)) {
11181130
members->totalDownloadedBytes += data.size();
11191131
double timeSinceStart = (WallTime::now() - members->downloadStartTime).seconds();
1120-
GST_TRACE_OBJECT(src, "R%u: downloaded %" G_GUINT64_FORMAT " bytes in %f seconds =~ %1.0f bytes/second", m_requestNumber, members->totalDownloadedBytes, timeSinceStart
1132+
GST_TRACE_OBJECT(src.get(), "R%u: downloaded %" G_GUINT64_FORMAT " bytes in %f seconds =~ %1.0f bytes/second", m_requestNumber, members->totalDownloadedBytes, timeSinceStart
11211133
, timeSinceStart ? members->totalDownloadedBytes / timeSinceStart : 0);
11221134
} else {
11231135
members->downloadStartTime = WallTime::now();
11241136
}
11251137

11261138
int length = data.size();
1127-
GST_LOG_OBJECT(src, "R%u: Have %d bytes of data", m_requestNumber, length);
1139+
GST_LOG_OBJECT(src.get(), "R%u: Have %d bytes of data", m_requestNumber, length);
11281140

11291141
members->readPosition += length;
11301142
ASSERT(!members->haveSize || members->readPosition <= members->size);
11311143

1132-
gst_element_post_message(GST_ELEMENT_CAST(src), gst_message_new_element(GST_OBJECT_CAST(src),
1144+
gst_element_post_message(GST_ELEMENT_CAST(src.get()), gst_message_new_element(GST_OBJECT_CAST(src.get()),
11331145
gst_structure_new("webkit-network-statistics", "read-position", G_TYPE_UINT64, members->readPosition, "size", G_TYPE_UINT64, members->size, nullptr)));
11341146

11351147
checkUpdateBlocksize(length);
11361148
GstBuffer* buffer = gstBufferNewWrappedFast(fastMemDup(data.data(), length), length);
11371149
gst_adapter_push(members->adapter.get(), buffer);
11381150

1139-
stopLoaderIfNeeded(src, members);
1151+
stopLoaderIfNeeded(src.get(), members);
11401152
members->responseCondition.notifyOne();
11411153
}
11421154

11431155
void CachedResourceStreamingClient::accessControlCheckFailed(PlatformMediaResource&, const ResourceError& error)
11441156
{
11451157
ASSERT(isMainThread());
1146-
WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
1158+
auto src = m_src.get();
1159+
if (!src)
1160+
return;
1161+
11471162
DataMutexLocker members { src->priv->dataMutex };
11481163
if (members->requestNumber != m_requestNumber)
11491164
return;
11501165

1151-
GST_ELEMENT_ERROR(src, RESOURCE, READ, ("R%u: %s", m_requestNumber, error.localizedDescription().utf8().data()), (nullptr));
1166+
GST_ELEMENT_ERROR(src.get(), RESOURCE, READ, ("R%u: %s", m_requestNumber, error.localizedDescription().utf8().data()), (nullptr));
11521167
members->doesHaveEOS = true;
11531168
members->responseCondition.notifyOne();
11541169
}
11551170

11561171
void CachedResourceStreamingClient::loadFailed(PlatformMediaResource&, const ResourceError& error)
11571172
{
11581173
ASSERT(isMainThread());
1159-
WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
1174+
auto src = m_src.get();
1175+
if (!src)
1176+
return;
1177+
11601178
DataMutexLocker members { src->priv->dataMutex };
11611179
if (members->requestNumber != m_requestNumber)
11621180
return;
11631181

11641182
if (!error.isCancellation()) {
1165-
GST_ERROR_OBJECT(src, "R%u: Have failure: %s", m_requestNumber, error.localizedDescription().utf8().data());
1166-
GST_ELEMENT_ERROR(src, RESOURCE, FAILED, ("R%u: %s", m_requestNumber, error.localizedDescription().utf8().data()), (nullptr));
1183+
GST_ERROR_OBJECT(src.get(), "R%u: Have failure: %s", m_requestNumber, error.localizedDescription().utf8().data());
1184+
GST_ELEMENT_ERROR(src.get(), RESOURCE, FAILED, ("R%u: %s", m_requestNumber, error.localizedDescription().utf8().data()), (nullptr));
11671185
} else
1168-
GST_LOG_OBJECT(src, "R%u: Request cancelled: %s", m_requestNumber, error.localizedDescription().utf8().data());
1186+
GST_LOG_OBJECT(src.get(), "R%u: Request cancelled: %s", m_requestNumber, error.localizedDescription().utf8().data());
11691187

11701188
members->doesHaveEOS = true;
11711189
members->responseCondition.notifyOne();
@@ -1174,12 +1192,15 @@ void CachedResourceStreamingClient::loadFailed(PlatformMediaResource&, const Res
11741192
void CachedResourceStreamingClient::loadFinished(PlatformMediaResource&, const NetworkLoadMetrics&)
11751193
{
11761194
ASSERT(isMainThread());
1177-
WebKitWebSrc* src = WEBKIT_WEB_SRC(m_src);
1195+
auto src = m_src.get();
1196+
if (!src)
1197+
return;
1198+
11781199
DataMutexLocker members { src->priv->dataMutex };
11791200
if (members->requestNumber != m_requestNumber)
11801201
return;
11811202

1182-
GST_LOG_OBJECT(src, "R%u: Load finished. Read position: %" G_GUINT64_FORMAT, m_requestNumber, members->readPosition);
1203+
GST_LOG_OBJECT(src.get(), "R%u: Load finished. Read position: %" G_GUINT64_FORMAT, m_requestNumber, members->readPosition);
11831204

11841205
members->doesHaveEOS = true;
11851206
members->responseCondition.notifyOne();

0 commit comments

Comments
 (0)