richard pushed to branch tor-browser-115.11.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
51f80eb6
by Kershaw Chang at 2024-05-10T22:22:15+02:00
-
cb7f8ec0
by Kershaw Chang at 2024-05-10T22:22:56+02:00
-
2e33d3b5
by Nika Layzell at 2024-05-10T22:37:57+02:00
-
bbb3af71
by Jonathan Kew at 2024-05-10T23:19:01+02:00
-
f87ae3f1
by alwu at 2024-05-10T23:34:34+02:00
8 changed files:
- dom/media/ipc/RemoteMediaDataDecoder.cpp
- dom/media/ipc/RemoteMediaDataDecoder.h
- dom/media/platforms/wrappers/MediaChangeMonitor.cpp
- dom/media/platforms/wrappers/MediaChangeMonitor.h
- gfx/thebes/gfxPlatformFontList.h
- modules/libpref/init/StaticPrefList.yaml
- netwerk/protocol/http/nsHttpDigestAuth.cpp
- uriloader/base/nsURILoader.cpp
Changes:
... | ... | @@ -18,7 +18,12 @@ namespace mozilla { |
18 | 18 | ##__VA_ARGS__)
|
19 | 19 | |
20 | 20 | RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild* aChild)
|
21 | - : mChild(aChild) {
|
|
21 | + : mChild(aChild),
|
|
22 | + mDescription("RemoteMediaDataDecoder"_ns),
|
|
23 | + mProcessName("unknown"_ns),
|
|
24 | + mCodecName("unknown"_ns),
|
|
25 | + mIsHardwareAccelerated(false),
|
|
26 | + mConversion(ConversionRequired::kNeedNone) {
|
|
22 | 27 | LOG("%p is created", this);
|
23 | 28 | }
|
24 | 29 | |
... | ... | @@ -48,6 +53,7 @@ RefPtr<MediaDataDecoder::InitPromise> RemoteMediaDataDecoder::Init() { |
48 | 53 | ->Then(
|
49 | 54 | RemoteDecoderManagerChild::GetManagerThread(), __func__,
|
50 | 55 | [self, this](TrackType aTrack) {
|
56 | + MutexAutoLock lock(mMutex);
|
|
51 | 57 | // If shutdown has started in the meantime shutdown promise may
|
52 | 58 | // be resloved before this task. In this case mChild will be null
|
53 | 59 | // and the init promise has to be canceled.
|
... | ... | @@ -127,6 +133,7 @@ RefPtr<ShutdownPromise> RemoteMediaDataDecoder::Shutdown() { |
127 | 133 | |
128 | 134 | bool RemoteMediaDataDecoder::IsHardwareAccelerated(
|
129 | 135 | nsACString& aFailureReason) const {
|
136 | + MutexAutoLock lock(mMutex);
|
|
130 | 137 | aFailureReason = mHardwareAcceleratedReason;
|
131 | 138 | return mIsHardwareAccelerated;
|
132 | 139 | }
|
... | ... | @@ -145,18 +152,24 @@ void RemoteMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime) { |
145 | 152 | |
146 | 153 | MediaDataDecoder::ConversionRequired RemoteMediaDataDecoder::NeedsConversion()
|
147 | 154 | const {
|
155 | + MutexAutoLock lock(mMutex);
|
|
148 | 156 | return mConversion;
|
149 | 157 | }
|
150 | 158 | |
151 | 159 | nsCString RemoteMediaDataDecoder::GetDescriptionName() const {
|
160 | + MutexAutoLock lock(mMutex);
|
|
152 | 161 | return mDescription;
|
153 | 162 | }
|
154 | 163 | |
155 | 164 | nsCString RemoteMediaDataDecoder::GetProcessName() const {
|
165 | + MutexAutoLock lock(mMutex);
|
|
156 | 166 | return mProcessName;
|
157 | 167 | }
|
158 | 168 | |
159 | -nsCString RemoteMediaDataDecoder::GetCodecName() const { return mCodecName; }
|
|
169 | +nsCString RemoteMediaDataDecoder::GetCodecName() const {
|
|
170 | + MutexAutoLock lock(mMutex);
|
|
171 | + return mCodecName;
|
|
172 | +}
|
|
160 | 173 | |
161 | 174 | #undef LOG
|
162 | 175 |
... | ... | @@ -53,14 +53,16 @@ class RemoteMediaDataDecoder final |
53 | 53 | // destructor when we can guarantee no other threads are accessing it). Only
|
54 | 54 | // read from the manager thread.
|
55 | 55 | RefPtr<RemoteDecoderChild> mChild;
|
56 | + |
|
57 | + mutable Mutex mMutex{"RemoteMediaDataDecoder"};
|
|
58 | + |
|
56 | 59 | // Only ever written/modified during decoder initialisation.
|
57 | - // As such can be accessed from any threads after that.
|
|
58 | - nsCString mDescription = "RemoteMediaDataDecoder"_ns;
|
|
59 | - nsCString mProcessName = "unknown"_ns;
|
|
60 | - nsCString mCodecName = "unknown"_ns;
|
|
61 | - bool mIsHardwareAccelerated = false;
|
|
62 | - nsCString mHardwareAcceleratedReason;
|
|
63 | - ConversionRequired mConversion = ConversionRequired::kNeedNone;
|
|
60 | + nsCString mDescription MOZ_GUARDED_BY(mMutex);
|
|
61 | + nsCString mProcessName MOZ_GUARDED_BY(mMutex);
|
|
62 | + nsCString mCodecName MOZ_GUARDED_BY(mMutex);
|
|
63 | + bool mIsHardwareAccelerated MOZ_GUARDED_BY(mMutex);
|
|
64 | + nsCString mHardwareAcceleratedReason MOZ_GUARDED_BY(mMutex);
|
|
65 | + ConversionRequired mConversion MOZ_GUARDED_BY(mMutex);
|
|
64 | 66 | };
|
65 | 67 | |
66 | 68 | } // namespace mozilla
|
... | ... | @@ -668,6 +668,7 @@ RefPtr<ShutdownPromise> MediaChangeMonitor::ShutdownDecoder() { |
668 | 668 | AssertOnThread();
|
669 | 669 | mConversionRequired.reset();
|
670 | 670 | if (mDecoder) {
|
671 | + MutexAutoLock lock(mMutex);
|
|
671 | 672 | RefPtr<MediaDataDecoder> decoder = std::move(mDecoder);
|
672 | 673 | return decoder->Shutdown();
|
673 | 674 | }
|
... | ... | @@ -715,6 +716,7 @@ MediaChangeMonitor::CreateDecoder() { |
715 | 716 | ->Then(
|
716 | 717 | GetCurrentSerialEventTarget(), __func__,
|
717 | 718 | [self = RefPtr{this}, this](RefPtr<MediaDataDecoder>&& aDecoder) {
|
719 | + MutexAutoLock lock(mMutex);
|
|
718 | 720 | mDecoder = std::move(aDecoder);
|
719 | 721 | DDLINKCHILD("decoder", mDecoder.get());
|
720 | 722 | return CreateDecoderPromise::CreateAndResolve(true, __func__);
|
... | ... | @@ -963,6 +965,11 @@ void MediaChangeMonitor::FlushThenShutdownDecoder( |
963 | 965 | ->Track(mFlushRequest);
|
964 | 966 | }
|
965 | 967 | |
968 | +MediaDataDecoder* MediaChangeMonitor::GetDecoderOnNonOwnerThread() const {
|
|
969 | + MutexAutoLock lock(mMutex);
|
|
970 | + return mDecoder;
|
|
971 | +}
|
|
972 | + |
|
966 | 973 | #undef LOG
|
967 | 974 | |
968 | 975 | } // namespace mozilla |
... | ... | @@ -41,34 +41,34 @@ class MediaChangeMonitor final |
41 | 41 | RefPtr<ShutdownPromise> Shutdown() override;
|
42 | 42 | bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
|
43 | 43 | nsCString GetDescriptionName() const override {
|
44 | - if (mDecoder) {
|
|
45 | - return mDecoder->GetDescriptionName();
|
|
44 | + if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
|
|
45 | + return decoder->GetDescriptionName();
|
|
46 | 46 | }
|
47 | 47 | return "MediaChangeMonitor decoder (pending)"_ns;
|
48 | 48 | }
|
49 | 49 | nsCString GetProcessName() const override {
|
50 | - if (mDecoder) {
|
|
51 | - return mDecoder->GetProcessName();
|
|
50 | + if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
|
|
51 | + return decoder->GetProcessName();
|
|
52 | 52 | }
|
53 | 53 | return "MediaChangeMonitor"_ns;
|
54 | 54 | }
|
55 | 55 | nsCString GetCodecName() const override {
|
56 | - if (mDecoder) {
|
|
57 | - return mDecoder->GetCodecName();
|
|
56 | + if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
|
|
57 | + return decoder->GetCodecName();
|
|
58 | 58 | }
|
59 | 59 | return "MediaChangeMonitor"_ns;
|
60 | 60 | }
|
61 | 61 | void SetSeekThreshold(const media::TimeUnit& aTime) override;
|
62 | 62 | bool SupportDecoderRecycling() const override {
|
63 | - if (mDecoder) {
|
|
64 | - return mDecoder->SupportDecoderRecycling();
|
|
63 | + if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
|
|
64 | + return decoder->SupportDecoderRecycling();
|
|
65 | 65 | }
|
66 | 66 | return false;
|
67 | 67 | }
|
68 | 68 | |
69 | 69 | ConversionRequired NeedsConversion() const override {
|
70 | - if (mDecoder) {
|
|
71 | - return mDecoder->NeedsConversion();
|
|
70 | + if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
|
|
71 | + return decoder->NeedsConversion();
|
|
72 | 72 | }
|
73 | 73 | // Default so no conversion is performed.
|
74 | 74 | return ConversionRequired::kNeedNone;
|
... | ... | @@ -97,6 +97,9 @@ class MediaChangeMonitor final |
97 | 97 | MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread());
|
98 | 98 | }
|
99 | 99 | |
100 | + // This is used for getting decoder debug info on other threads. Thread-safe.
|
|
101 | + MediaDataDecoder* GetDecoderOnNonOwnerThread() const;
|
|
102 | + |
|
100 | 103 | bool CanRecycleDecoder() const;
|
101 | 104 | |
102 | 105 | typedef MozPromise<bool, MediaResult, true /* exclusive */>
|
... | ... | @@ -137,6 +140,13 @@ class MediaChangeMonitor final |
137 | 140 | const CreateDecoderParamsForAsync mParams;
|
138 | 141 | // Keep any seek threshold set for after decoder creation and initialization.
|
139 | 142 | Maybe<media::TimeUnit> mPendingSeekThreshold;
|
143 | + |
|
144 | + // This lock is used for mDecoder specifically, but it doens't need to be used
|
|
145 | + // for every places accessing mDecoder which is mostly on the owner thread.
|
|
146 | + // However, when requesting decoder debug info, it can happen on other
|
|
147 | + // threads, so we need this mutex to avoid the data race of
|
|
148 | + // creating/destroying decoder and accessing decoder's debug info.
|
|
149 | + mutable Mutex MOZ_ANNOTATED mMutex{"MediaChangeMonitor"};
|
|
140 | 150 | };
|
141 | 151 | |
142 | 152 | } // namespace mozilla
|
... | ... | @@ -124,7 +124,7 @@ class ShmemCharMapHashEntry final : public PLDHashEntryHdr { |
124 | 124 | return aCharMap->GetChecksum();
|
125 | 125 | }
|
126 | 126 | |
127 | - enum { ALLOW_MEMMOVE = true };
|
|
127 | + enum { ALLOW_MEMMOVE = false }; // because of the Pointer member
|
|
128 | 128 | |
129 | 129 | private:
|
130 | 130 | // charMaps are stored in the shared memory that FontList objects point to,
|
... | ... | @@ -12787,6 +12787,18 @@ |
12787 | 12787 | value: true
|
12788 | 12788 | mirror: always
|
12789 | 12789 | |
12790 | + # The length of cnonce string used in HTTP digest auth.
|
|
12791 | +- name: network.http.digest_auth_cnonce_length
|
|
12792 | + type: uint32_t
|
|
12793 | + value: 16
|
|
12794 | + mirror: always
|
|
12795 | + |
|
12796 | + # If true, HTTP response content-type headers will be parsed using the standards-compliant MimeType parser
|
|
12797 | +- name: network.standard_content_type_parsing.response_headers
|
|
12798 | + type: RelaxedAtomicBool
|
|
12799 | + value: true
|
|
12800 | + mirror: always
|
|
12801 | + |
|
12790 | 12802 | # The maximum count that we allow socket prrocess to crash. If this count is
|
12791 | 12803 | # reached, we won't use networking over socket process.
|
12792 | 12804 | - name: network.max_socket_process_failed_count
|
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 | |
10 | 10 | #include "mozilla/ClearOnShutdown.h"
|
11 | 11 | #include "mozilla/Sprintf.h"
|
12 | +#include "mozilla/StaticPrefs_network.h"
|
|
12 | 13 | #include "mozilla/Unused.h"
|
13 | 14 | |
14 | 15 | #include "nsHttp.h"
|
... | ... | @@ -22,6 +23,7 @@ |
22 | 23 | #include "nsCRT.h"
|
23 | 24 | #include "nsICryptoHash.h"
|
24 | 25 | #include "nsComponentManagerUtils.h"
|
26 | +#include "pk11pub.h"
|
|
25 | 27 | |
26 | 28 | constexpr uint16_t DigestLength(uint16_t aAlgorithm) {
|
27 | 29 | if (aAlgorithm & (ALGO_SHA256 | ALGO_SHA256_SESS)) {
|
... | ... | @@ -321,9 +323,13 @@ nsHttpDigestAuth::GenerateCredentials( |
321 | 323 | // returned Authentication-Info header). also used for session info.
|
322 | 324 | //
|
323 | 325 | nsAutoCString cnonce;
|
324 | - static const char hexChar[] = "0123456789abcdef";
|
|
325 | - for (int i = 0; i < 16; ++i) {
|
|
326 | - cnonce.Append(hexChar[(int)(15.0 * rand() / (RAND_MAX + 1.0))]);
|
|
326 | + nsTArray<uint8_t> cnonceBuf;
|
|
327 | + cnonceBuf.SetLength(StaticPrefs::network_http_digest_auth_cnonce_length() /
|
|
328 | + 2);
|
|
329 | + PK11_GenerateRandom(reinterpret_cast<unsigned char*>(cnonceBuf.Elements()),
|
|
330 | + cnonceBuf.Length());
|
|
331 | + for (auto byte : cnonceBuf) {
|
|
332 | + cnonce.AppendPrintf("%02x", byte);
|
|
327 | 333 | }
|
328 | 334 | LOG((" cnonce=%s\n", cnonce.get()));
|
329 | 335 |
... | ... | @@ -414,28 +414,28 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest* request) { |
414 | 414 | NS_ASSERTION(!m_targetStreamListener,
|
415 | 415 | "If we found a listener, why are we not using it?");
|
416 | 416 | |
417 | - if (mFlags & nsIURILoader::DONT_RETARGET) {
|
|
418 | - LOG(
|
|
419 | - (" External handling forced or (listener not interested and no "
|
|
420 | - "stream converter exists), and retargeting disallowed -> aborting"));
|
|
421 | - return NS_ERROR_WONT_HANDLE_CONTENT;
|
|
422 | - }
|
|
423 | - |
|
424 | 417 | // Before dispatching to the external helper app service, check for an HTTP
|
425 | 418 | // error page. If we got one, we don't want to handle it with a helper app,
|
426 | 419 | // really.
|
427 | - // The WPT a-download-click-404.html requires us to silently handle this
|
|
428 | - // without displaying an error page, so we just return early here.
|
|
429 | - // See bug 1604308 for discussion around what the ideal behaviour is.
|
|
430 | 420 | nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
|
431 | 421 | if (httpChannel) {
|
432 | 422 | bool requestSucceeded;
|
433 | 423 | rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
|
434 | 424 | if (NS_FAILED(rv) || !requestSucceeded) {
|
435 | - return NS_OK;
|
|
425 | + LOG(
|
|
426 | + (" Returning NS_ERROR_FILE_NOT_FOUND from "
|
|
427 | + "nsDocumentOpenInfo::DispatchContent due to failed HTTP response"));
|
|
428 | + return NS_ERROR_FILE_NOT_FOUND;
|
|
436 | 429 | }
|
437 | 430 | }
|
438 | 431 | |
432 | + if (mFlags & nsIURILoader::DONT_RETARGET) {
|
|
433 | + LOG(
|
|
434 | + (" External handling forced or (listener not interested and no "
|
|
435 | + "stream converter exists), and retargeting disallowed -> aborting"));
|
|
436 | + return NS_ERROR_WONT_HANDLE_CONTENT;
|
|
437 | + }
|
|
438 | + |
|
439 | 439 | // Fifth step:
|
440 | 440 | //
|
441 | 441 | // All attempts to dispatch this content have failed. Just pass it off to
|