From df4ca1467257e9554dc24e9f4784f8edefb52e0a Mon Sep 17 00:00:00 2001 From: zhangjing Date: Thu, 18 Aug 2022 17:21:53 +0800 Subject: [PATCH] =?UTF-8?q?chromium=E5=AE=89=E5=85=A8=E6=BC=8F=E6=B4=9E?= =?UTF-8?q?=E5=9B=9E=E5=90=88release3.1=E4=BF=AE=E5=A4=8Dpatch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangjing --- patch/Release-816.patch | 594 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 594 insertions(+) create mode 100644 patch/Release-816.patch diff --git a/patch/Release-816.patch b/patch/Release-816.patch new file mode 100644 index 0000000..4c7f05e --- /dev/null +++ b/patch/Release-816.patch @@ -0,0 +1,594 @@ +diff --git a/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc b/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc +index 79c9ee5597..e5833968c1 100644 +--- a/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc ++++ b/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.cc +@@ -18,7 +18,8 @@ CloseBubbleOnTabActivationHelper::CloseBubbleOnTabActivationHelper( + } + + CloseBubbleOnTabActivationHelper::~CloseBubbleOnTabActivationHelper() { +- browser_->tab_strip_model()->RemoveObserver(this); ++ if (browser_) ++ browser_->tab_strip_model()->RemoveObserver(this); + } + + void CloseBubbleOnTabActivationHelper::OnTabStripModelChanged( +@@ -35,3 +36,10 @@ void CloseBubbleOnTabActivationHelper::OnTabStripModelChanged( + owner_bubble_ = nullptr; + } + } ++ ++void CloseBubbleOnTabActivationHelper::OnTabStripModelDestroyed( ++ TabStripModel* tab_strip_model) { ++ DCHECK(browser_); ++ browser_->tab_strip_model()->RemoveObserver(this); ++ browser_ = nullptr; ++} +diff --git a/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h b/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h +index 7fd05cefbd..486b6d1c57 100644 +--- a/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h ++++ b/src/chrome/browser/ui/views/close_bubble_on_tab_activation_helper.h +@@ -30,6 +30,7 @@ class CloseBubbleOnTabActivationHelper : public TabStripModelObserver { + TabStripModel* tab_strip_model, + const TabStripModelChange& change, + const TabStripSelectionChange& selection) override; ++ void OnTabStripModelDestroyed(TabStripModel* tab_strip_model) override; + + private: + views::BubbleDialogDelegateView* owner_bubble_; // weak, owns me. +diff --git a/src/content/browser/service_worker/service_worker_version.cc b/src/content/browser/service_worker/service_worker_version.cc +index faf73f0285..6dc6a4fae0 100644 +--- a/src/content/browser/service_worker/service_worker_version.cc ++++ b/src/content/browser/service_worker/service_worker_version.cc +@@ -1970,6 +1970,11 @@ void ServiceWorkerVersion::OnTimeoutTimer() { + + MarkIfStale(); + ++ // Global `this` protecter. ++ // callbacks initiated by this function sometimes reduce refcnt to 0 ++ // to make this instance freed. ++ scoped_refptr protect_this(this); ++ + // Stopping the worker hasn't finished within a certain period. + if (GetTickDuration(stop_time_) > kStopWorkerTimeout) { + DCHECK_EQ(EmbeddedWorkerStatus::STOPPING, running_status()); +@@ -1980,12 +1985,6 @@ void ServiceWorkerVersion::OnTimeoutTimer() { + ReportError(blink::ServiceWorkerStatusCode::kErrorTimeout, + "DETACH_STALLED_IN_STOPPING"); + +- // Detach the worker. Remove |this| as a listener first; otherwise +- // OnStoppedInternal might try to restart before the new worker +- // is created. Also, protect |this|, since swapping out the +- // EmbeddedWorkerInstance could destroy our ServiceWorkerHost which could in +- // turn destroy |this|. +- scoped_refptr protect_this(this); + embedded_worker_->RemoveObserver(this); + embedded_worker_->Detach(); + embedded_worker_ = std::make_unique(this); +@@ -2012,7 +2011,6 @@ void ServiceWorkerVersion::OnTimeoutTimer() { + DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || + running_status() == EmbeddedWorkerStatus::STOPPING) + << static_cast(running_status()); +- scoped_refptr protect(this); + FinishStartWorker(blink::ServiceWorkerStatusCode::kErrorTimeout); + if (running_status() == EmbeddedWorkerStatus::STARTING) + embedded_worker_->Stop(); +@@ -2021,17 +2019,26 @@ void ServiceWorkerVersion::OnTimeoutTimer() { + + // Requests have not finished before their expiration. + bool stop_for_timeout = false; +- auto timeout_iter = request_timeouts_.begin(); +- while (timeout_iter != request_timeouts_.end()) { ++ // In case, `request_timeouts_` can be modified in the callbacks initiated ++ // in `MaybeTimeoutRequest`, we keep its contents locally during the ++ // following while loop. ++ std::set request_timeouts; ++ request_timeouts.swap(request_timeouts_); ++ auto timeout_iter = request_timeouts.begin(); ++ while (timeout_iter != request_timeouts.end()) { + const InflightRequestTimeoutInfo& info = *timeout_iter; +- if (!RequestExpired(info.expiration)) ++ if (!RequestExpired(info.expiration)) { + break; ++ } + if (MaybeTimeoutRequest(info)) { + stop_for_timeout = + stop_for_timeout || info.timeout_behavior == KILL_ON_TIMEOUT; + } +- timeout_iter = request_timeouts_.erase(timeout_iter); ++ timeout_iter = request_timeouts.erase(timeout_iter); + } ++ // Ensure the `request_timeouts_` won't be touched during the loop. ++ DCHECK(request_timeouts_.empty()); ++ request_timeouts_.swap(request_timeouts); + if (stop_for_timeout && running_status() != EmbeddedWorkerStatus::STOPPING) + embedded_worker_->Stop(); + +diff --git a/src/content/browser/service_worker/service_worker_version.h b/src/content/browser/service_worker/service_worker_version.h +index 1db322ab68..f1c63f2a8a 100644 +--- a/src/content/browser/service_worker/service_worker_version.h ++++ b/src/content/browser/service_worker/service_worker_version.h +@@ -851,6 +851,8 @@ class CONTENT_EXPORT ServiceWorkerVersion + bool is_browser_startup_complete, + blink::ServiceWorkerStatusCode status); + ++ // The caller of MaybeTimeoutRequest must increase reference count of |this| ++ // to avoid it deleted during the execution. + bool MaybeTimeoutRequest(const InflightRequestTimeoutInfo& info); + void SetAllRequestExpirations(const base::TimeTicks& expiration); + +diff --git a/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc b/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc +index 2e9c330e67..12f7b4b440 100644 +--- a/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc ++++ b/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.cc +@@ -66,7 +66,7 @@ void JavaScriptDialogHelper::RunJavaScriptDialog( + web_view_permission_helper->RequestPermission( + WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG, request_info, + base::BindOnce(&JavaScriptDialogHelper::OnPermissionResponse, +- base::Unretained(this), std::move(callback)), ++ weak_factory_.GetWeakPtr(), std::move(callback)), + false /* allowed_by_default */); + } + +diff --git a/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.h b/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.h +index ae759a14c1..125977727f 100644 +--- a/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.h ++++ b/src/extensions/browser/guest_view/web_view/javascript_dialog_helper.h +@@ -6,6 +6,7 @@ + #define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_JAVASCRIPT_DIALOG_HELPER_H_ + + #include "base/macros.h" ++#include "base/memory/weak_ptr.h" + #include "content/public/browser/javascript_dialog_manager.h" + + namespace extensions { +@@ -43,6 +44,8 @@ class JavaScriptDialogHelper : public content::JavaScriptDialogManager { + // Pointer to the webview that is being helped. + WebViewGuest* const web_view_guest_; + ++ base::WeakPtrFactory weak_factory_{this}; ++ + DISALLOW_COPY_AND_ASSIGN(JavaScriptDialogHelper); + }; + +diff --git a/src/third_party/blink/web_tests/fast/peerconnection/simulcast-munge.html b/src/third_party/blink/web_tests/fast/peerconnection/simulcast-munge.html +new file mode 100644 +index 0000000000..2e6dcf9269 +--- /dev/null ++++ b/src/third_party/blink/web_tests/fast/peerconnection/simulcast-munge.html +@@ -0,0 +1,50 @@ ++ ++ ++ ++ Simulcast manipulation ++ ++ ++ ++ ++ ++ +\ No newline at end of file +diff --git a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.cpp b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.cpp +index 422f92b257..616b6f123a 100644 +--- a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.cpp ++++ b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.cpp +@@ -10,6 +10,7 @@ + #include + + #include "core/fpdfapi/parser/cpdf_boolean.h" ++#include "core/fpdfapi/parser/cpdf_dictionary.h" + #include "core/fpdfapi/parser/cpdf_name.h" + #include "core/fpdfapi/parser/cpdf_number.h" + #include "core/fpdfapi/parser/cpdf_reference.h" +@@ -143,6 +144,10 @@ float CPDF_Array::GetNumberAt(size_t index) const { + return m_Objects[index]->GetNumber(); + } + ++RetainPtr CPDF_Array::GetMutableDictAt(size_t index) { ++ return pdfium::WrapRetain(GetDictAt(index)); ++} ++ + CPDF_Dictionary* CPDF_Array::GetDictAt(size_t index) { + CPDF_Object* p = GetDirectObjectAt(index); + if (!p) +diff --git a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.h b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.h +index 37b1af9592..7945eadb5b 100644 +--- a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.h ++++ b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_array.h +@@ -45,7 +45,8 @@ class CPDF_Array final : public CPDF_Object { + bool GetBooleanAt(size_t index, bool bDefault) const; + int GetIntegerAt(size_t index) const; + float GetNumberAt(size_t index) const; +- CPDF_Dictionary* GetDictAt(size_t index); ++ RetainPtr GetMutableDictAt(size_t index); ++ CPDF_Dictionary* GetDictAt(size_t index); // prefer previous form. + const CPDF_Dictionary* GetDictAt(size_t index) const; + CPDF_Stream* GetStreamAt(size_t index); + const CPDF_Stream* GetStreamAt(size_t index) const; +diff --git a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp +index 0ded422ed3..045339e8e2 100644 +--- a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp ++++ b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.cpp +@@ -147,6 +147,11 @@ float CPDF_Dictionary::GetNumberFor(const ByteString& key) const { + return p ? p->GetNumber() : 0; + } + ++RetainPtr CPDF_Dictionary::GetMutableDictFor( ++ const ByteString& key) { ++ return pdfium::WrapRetain(GetDictFor(key)); ++} ++ + const CPDF_Dictionary* CPDF_Dictionary::GetDictFor( + const ByteString& key) const { + const CPDF_Object* p = GetDirectObjectFor(key); +@@ -164,6 +169,11 @@ CPDF_Dictionary* CPDF_Dictionary::GetDictFor(const ByteString& key) { + static_cast(this)->GetDictFor(key)); + } + ++RetainPtr CPDF_Dictionary::GetMutableArrayFor( ++ const ByteString& key) { ++ return pdfium::WrapRetain(GetArrayFor(key)); ++} ++ + const CPDF_Array* CPDF_Dictionary::GetArrayFor(const ByteString& key) const { + return ToArray(GetDirectObjectFor(key)); + } +diff --git a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h +index cc23730bf8..65e939c837 100644 +--- a/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h ++++ b/src/third_party/pdfium/core/fpdfapi/parser/cpdf_dictionary.h +@@ -66,9 +66,11 @@ class CPDF_Dictionary final : public CPDF_Object { + int GetIntegerFor(const ByteString& key, int default_int) const; + float GetNumberFor(const ByteString& key) const; + const CPDF_Dictionary* GetDictFor(const ByteString& key) const; +- CPDF_Dictionary* GetDictFor(const ByteString& key); ++ CPDF_Dictionary* GetDictFor(const ByteString& key); // Prefer next form. ++ RetainPtr GetMutableDictFor(const ByteString& key); + const CPDF_Array* GetArrayFor(const ByteString& key) const; +- CPDF_Array* GetArrayFor(const ByteString& key); ++ CPDF_Array* GetArrayFor(const ByteString& key); // Prefer next form. ++ RetainPtr GetMutableArrayFor(const ByteString& key); + const CPDF_Stream* GetStreamFor(const ByteString& key) const; + CPDF_Stream* GetStreamFor(const ByteString& key); + CFX_FloatRect GetRectFor(const ByteString& key) const; +diff --git a/src/third_party/pdfium/core/fpdfdoc/cpdf_nametree.cpp b/src/third_party/pdfium/core/fpdfdoc/cpdf_nametree.cpp +index 546a57331f..512a284b52 100644 +--- a/src/third_party/pdfium/core/fpdfdoc/cpdf_nametree.cpp ++++ b/src/third_party/pdfium/core/fpdfdoc/cpdf_nametree.cpp +@@ -39,7 +39,7 @@ std::pair GetNodeLimitsMaybeSwap(CPDF_Array* pLimits) { + // Get the limit arrays that leaf array |pFind| is under in the tree with root + // |pNode|. |pLimits| will hold all the limit arrays from the leaf up to before + // the root. Return true if successful. +-bool GetNodeAncestorsLimits(CPDF_Dictionary* pNode, ++bool GetNodeAncestorsLimits(const RetainPtr& pNode, + const CPDF_Array* pFind, + int nLevel, + std::vector* pLimits) { +@@ -56,7 +56,7 @@ bool GetNodeAncestorsLimits(CPDF_Dictionary* pNode, + return false; + + for (size_t i = 0; i < pKids->size(); ++i) { +- CPDF_Dictionary* pKid = pKids->GetDictAt(i); ++ RetainPtr pKid = pKids->GetMutableDictAt(i); + if (!pKid) + continue; + +@@ -156,21 +156,21 @@ bool UpdateNodesAndLimitsUponDeletion(CPDF_Dictionary* pNode, + // will be the index of |csName| in |ppFind|. If |csName| is not found, |ppFind| + // will be the leaf array that |csName| should be added to, and |pFindIndex| + // will be the index that it should be added at. +-CPDF_Object* SearchNameNodeByName(CPDF_Dictionary* pNode, ++CPDF_Object* SearchNameNodeByName(const RetainPtr& pNode, + const WideString& csName, + int nLevel, + size_t* nIndex, +- CPDF_Array** ppFind, ++ RetainPtr* ppFind, + int* pFindIndex) { + if (nLevel > kNameTreeMaxRecursion) + return nullptr; + +- CPDF_Array* pLimits = pNode->GetArrayFor("Limits"); +- CPDF_Array* pNames = pNode->GetArrayFor("Names"); ++ RetainPtr pLimits = pNode->GetMutableArrayFor("Limits"); ++ RetainPtr pNames = pNode->GetMutableArrayFor("Names"); + if (pLimits) { + WideString csLeft; + WideString csRight; +- std::tie(csLeft, csRight) = GetNodeLimitsMaybeSwap(pLimits); ++ std::tie(csLeft, csRight) = GetNodeLimitsMaybeSwap(pLimits.Get()); + // Skip this node if the name to look for is smaller than its lower limit. + if (csName.Compare(csLeft) < 0) + return nullptr; +@@ -210,12 +210,12 @@ CPDF_Object* SearchNameNodeByName(CPDF_Dictionary* pNode, + } + + // Search through the node's children. +- CPDF_Array* pKids = pNode->GetArrayFor("Kids"); ++ RetainPtr pKids = pNode->GetMutableArrayFor("Kids"); + if (!pKids) + return nullptr; + + for (size_t i = 0; i < pKids->size(); i++) { +- CPDF_Dictionary* pKid = pKids->GetDictAt(i); ++ RetainPtr pKid = pKids->GetMutableDictAt(i); + if (!pKid) + continue; + +@@ -236,7 +236,7 @@ CPDF_Object* SearchNameNodeByIndex(CPDF_Dictionary* pNode, + int nLevel, + size_t* nCurIndex, + WideString* csName, +- CPDF_Array** ppFind, ++ RetainPtr* ppFind, + int* pFindIndex) { + if (nLevel > kNameTreeMaxRecursion) + return nullptr; +@@ -395,17 +395,17 @@ size_t CPDF_NameTree::GetCount() const { + bool CPDF_NameTree::AddValueAndName(RetainPtr pObj, + const WideString& name) { + size_t nIndex = 0; +- CPDF_Array* pFind = nullptr; ++ RetainPtr pFind; + int nFindIndex = -1; + // Handle the corner case where the root node is empty. i.e. No kids and no + // names. In which case, just insert into it and skip all the searches. +- CPDF_Array* pNames = m_pRoot->GetArrayFor("Names"); ++ RetainPtr pNames = m_pRoot->GetMutableArrayFor("Names"); + if (pNames && pNames->IsEmpty() && !m_pRoot->GetArrayFor("Kids")) + pFind = pNames; + + if (!pFind) { + // Fail if the tree already contains this name or if the tree is too deep. +- if (SearchNameNodeByName(m_pRoot.Get(), name, 0, &nIndex, &pFind, ++ if (SearchNameNodeByName(m_pRoot, name, 0, &nIndex, &pFind, + &nFindIndex)) { + return false; + } +@@ -435,7 +435,7 @@ bool CPDF_NameTree::AddValueAndName(RetainPtr pObj, + // Expand the limits that the newly added name is under, if the name falls + // outside of the limits of its leaf array or any arrays above it. + std::vector pLimits; +- GetNodeAncestorsLimits(m_pRoot.Get(), pFind, 0, &pLimits); ++ GetNodeAncestorsLimits(m_pRoot, pFind.Get(), 0, &pLimits); + for (auto* pLimit : pLimits) { + if (!pLimit) + continue; +@@ -452,7 +452,7 @@ bool CPDF_NameTree::AddValueAndName(RetainPtr pObj, + bool CPDF_NameTree::DeleteValueAndName(int nIndex) { + size_t nCurIndex = 0; + WideString csName; +- CPDF_Array* pFind = nullptr; ++ RetainPtr pFind; + int nFindIndex = -1; + // Fail if the tree does not contain |nIndex|. + if (!SearchNameNodeByIndex(m_pRoot.Get(), nIndex, 0, &nCurIndex, &csName, +@@ -465,7 +465,7 @@ bool CPDF_NameTree::DeleteValueAndName(int nIndex) { + pFind->RemoveAt(nFindIndex * 2); + + // Delete empty nodes and update the limits of |pFind|'s ancestors as needed. +- UpdateNodesAndLimitsUponDeletion(m_pRoot.Get(), pFind, csName, 0); ++ UpdateNodesAndLimitsUponDeletion(m_pRoot.Get(), pFind.Get(), csName, 0); + return true; + } + +@@ -479,7 +479,7 @@ CPDF_Object* CPDF_NameTree::LookupValueAndName(int nIndex, + + CPDF_Object* CPDF_NameTree::LookupValue(const WideString& csName) const { + size_t nIndex = 0; +- return SearchNameNodeByName(m_pRoot.Get(), csName, 0, &nIndex, nullptr, ++ return SearchNameNodeByName(m_pRoot, csName, 0, &nIndex, nullptr, + nullptr); + } + +diff --git a/src/third_party/pdfium/testing/resources/javascript/bug_1335681.in b/src/third_party/pdfium/testing/resources/javascript/bug_1335681.in +new file mode 100644 +index 0000000000..254e596451 +--- /dev/null ++++ b/src/third_party/pdfium/testing/resources/javascript/bug_1335681.in +@@ -0,0 +1,38 @@ ++{{header}} ++{{object 1 0}} << ++ /Pages 1 0 R ++ /OpenAction 2 0 R ++ /Names << ++ /Dests 3 0 R ++ >> ++>> ++endobj ++{{object 2 0}} << ++ /Type /Action ++ /S /JavaScript ++ /JS ( ++ app.alert\("Starting"\); ++ this.gotoNamedDest\(""\); ++ ) ++>> ++endobj ++{{object 3 0}} << ++ /Kids 4 0 R ++>> ++endobj ++{{object 4 0}} [ ++ << >> ++ << >> ++ << ++ /Kids [ ++ << ++ /Limits 4 0 R ++ >> ++ ] ++ >> ++] ++endobj ++{{xref}} ++{{trailer}} ++{{startxref}} ++%%EOF +diff --git a/src/third_party/pdfium/testing/resources/javascript/bug_1335681_expected.txt b/src/third_party/pdfium/testing/resources/javascript/bug_1335681_expected.txt +new file mode 100644 +index 0000000000..80a6951c49 +--- /dev/null ++++ b/src/third_party/pdfium/testing/resources/javascript/bug_1335681_expected.txt +@@ -0,0 +1 @@ ++Alert: Starting +diff --git a/src/third_party/webrtc/pc/peer_connection_simulcast_unittest.cc b/src/third_party/webrtc/pc/peer_connection_simulcast_unittest.cc +index 8822a980f7..3476429811 100644 +--- a/src/third_party/webrtc/pc/peer_connection_simulcast_unittest.cc ++++ b/src/third_party/webrtc/pc/peer_connection_simulcast_unittest.cc +@@ -556,6 +556,27 @@ TEST_F(PeerConnectionSimulcastTests, NegotiationDoesNotHaveRidExtension) { + ValidateTransceiverParameters(transceiver, expected_layers); + } + ++// Check that modifying the offer to remove simulcast and at the same ++// time leaving in a RID line does not cause an exception. ++TEST_F(PeerConnectionSimulcastTests, SimulcastSldModificationRejected) { ++ auto local = CreatePeerConnectionWrapper(); ++ auto remote = CreatePeerConnectionWrapper(); ++ auto layers = CreateLayers({"1", "2", "3"}, true); ++ AddTransceiver(local.get(), layers); ++ auto offer = local->CreateOffer(); ++ std::string as_string; ++ EXPECT_TRUE(offer->ToString(&as_string)); ++ auto simulcast_marker = "a=rid:3 send\r\na=simulcast:send 1;2;3\r\n"; ++ auto pos = as_string.find(simulcast_marker); ++ EXPECT_NE(pos, std::string::npos); ++ as_string.erase(pos, strlen(simulcast_marker)); ++ SdpParseError parse_error; ++ auto modified_offer = ++ CreateSessionDescription(SdpType::kOffer, as_string, &parse_error); ++ EXPECT_TRUE(modified_offer); ++ EXPECT_TRUE(local->SetLocalDescription(std::move(modified_offer))); ++} ++ + #if RTC_METRICS_ENABLED + // + // Checks the logged metrics when simulcast is not used. +diff --git a/src/third_party/webrtc/pc/rtp_sender.cc b/src/third_party/webrtc/pc/rtp_sender.cc +index 7026dd9db7..e3db51fffb 100644 +--- a/src/third_party/webrtc/pc/rtp_sender.cc ++++ b/src/third_party/webrtc/pc/rtp_sender.cc +@@ -291,8 +291,8 @@ void RtpSenderBase::SetSsrc(uint32_t ssrc) { + // we need to copy. + RtpParameters current_parameters = + media_channel_->GetRtpSendParameters(ssrc_); +- RTC_DCHECK_GE(current_parameters.encodings.size(), +- init_parameters_.encodings.size()); ++ RTC_CHECK_GE(current_parameters.encodings.size(), ++ init_parameters_.encodings.size()); + for (size_t i = 0; i < init_parameters_.encodings.size(); ++i) { + init_parameters_.encodings[i].ssrc = + current_parameters.encodings[i].ssrc; +diff --git a/src/third_party/webrtc/pc/rtp_sender_receiver_unittest.cc b/src/third_party/webrtc/pc/rtp_sender_receiver_unittest.cc +index 364e87a89f..7a32cb0d9d 100644 +--- a/src/third_party/webrtc/pc/rtp_sender_receiver_unittest.cc ++++ b/src/third_party/webrtc/pc/rtp_sender_receiver_unittest.cc +@@ -1120,6 +1120,44 @@ TEST_F(RtpSenderReceiverTest, + DestroyVideoRtpSender(); + } + ++#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) ++using RtpSenderReceiverDeathTest = RtpSenderReceiverTest; ++ ++TEST_F(RtpSenderReceiverDeathTest, ++ VideoSenderManualRemoveSimulcastFailsDeathTest) { ++ AddVideoTrack(false); ++ ++ std::unique_ptr set_streams_observer = ++ std::make_unique(); ++ video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(), ++ set_streams_observer.get()); ++ ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get())); ++ EXPECT_CALL(*set_streams_observer, OnSetStreams()); ++ video_rtp_sender_->SetStreams({local_stream_->id()}); ++ ++ std::vector init_encodings(2); ++ init_encodings[0].max_bitrate_bps = 60000; ++ init_encodings[1].max_bitrate_bps = 120000; ++ video_rtp_sender_->set_init_send_encodings(init_encodings); ++ ++ RtpParameters params = video_rtp_sender_->GetParameters(); ++ ASSERT_EQ(2u, params.encodings.size()); ++ EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000); ++ ++ // Simulate the setLocalDescription call as if the user used SDP munging ++ // to disable simulcast. ++ std::vector ssrcs; ++ ssrcs.reserve(2); ++ for (int i = 0; i < 2; ++i) ++ ssrcs.push_back(kVideoSsrcSimulcast + i); ++ cricket::StreamParams stream_params = ++ cricket::StreamParams::CreateLegacy(kVideoSsrc); ++ video_media_channel()->AddSendStream(stream_params); ++ video_rtp_sender_->SetMediaChannel(video_media_channel()); ++ EXPECT_DEATH(video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast), ""); ++} ++#endif ++ + TEST_F(RtpSenderReceiverTest, + VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) { + video_rtp_sender_ = +diff --git a/src/third_party/webrtc/pc/webrtc_sdp.cc b/src/third_party/webrtc/pc/webrtc_sdp.cc +index 26eb4f30fd..b732bc829d 100644 +--- a/src/third_party/webrtc/pc/webrtc_sdp.cc ++++ b/src/third_party/webrtc/pc/webrtc_sdp.cc +@@ -3332,7 +3332,6 @@ bool ParseContent(const std::string& message, + + // If simulcast is specifed, split the rids into send and receive. + // Rids that do not appear in simulcast attribute will be removed. +- // If it is not specified, we assume that all rids are for send layers. + std::vector send_rids; + std::vector receive_rids; + if (!simulcast.empty()) { +@@ -3359,7 +3358,11 @@ bool ParseContent(const std::string& message, + + media_desc->set_simulcast_description(simulcast); + } else { +- send_rids = rids; ++ // RID is specified in RFC 8851, which identifies a lot of usages. ++ // We only support RFC 8853 usage of RID, not anything else. ++ // Ignore all RID parameters when a=simulcast is missing. ++ // In particular do NOT do send_rids = rids; ++ RTC_LOG(LS_VERBOSE) << "Ignoring send_rids without simulcast"; + } + + media_desc->set_receive_rids(receive_rids); -- Gitee