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
|