
ma1 pushed to branch tor-browser-128.14.0esr-14.5-1 at The Tor Project / Applications / Tor Browser Commits: 2886bc79 by Emma Zuehlcke at 2025-09-15T17:37:23+02:00 Bug 1665334, r=mconley,fluent-reviewers,bolsson Differential Revision: https://phabricator.services.mozilla.com/D257293 - - - - - f26c48dc by Daniel Holbert at 2025-09-15T19:00:18+02:00 Bug 1970490: Use loading principal (rather than triggering principal) for CORS checks, by default. a=RyanVM This is essentially a backout of bug 1496505, putting its change behind a new off-by-default about:config pref[1] for now, in case there are use cases that require it. [1] content.cors.use_triggering_principal Original Revision: https://phabricator.services.mozilla.com/D252611 Differential Revision: https://phabricator.services.mozilla.com/D263611 - - - - - 6c8a1f0f by Makoto Kato at 2025-09-15T19:21:35+02:00 Bug 1974025 - Check scheme into Intent data. r=geckoview-reviewers,tcampbell,nalexander a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D256952 - - - - - 81543294 by Jon Coppeard at 2025-09-15T19:34:28+02:00 Bug 1979502 - Check slices vector not empty before accessing the last slice r=sfink a=RyanVM |aborted| is reset to false at the end of a slice but GCRuntime::waitBackgroundSweepEnd can be called outside of a slice. Differential Revision: https://phabricator.services.mozilla.com/D260685 - - - - - 11317e5a by longsonr at 2025-09-15T19:55:19+02:00 Bug 1980788 - Use std::size rather than hardcoding an array size a=RyanVM DONTBUILD Original Revision: https://phabricator.services.mozilla.com/D262967 Differential Revision: https://phabricator.services.mozilla.com/D263131 - - - - - 9b2fe8ef by Lee Salzman at 2025-09-15T19:59:04+02:00 Bug 1981283. r=ahale a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D260412 - - - - - 2517a786 by Jed Davis at 2025-09-15T20:07:53+02:00 Bug 1982763 - Re-add `CLONE_NEWIPC` to the Linux GMP sandbox. a=RyanVM Original Revision: https://phabricator.services.mozilla.com/D260923 Differential Revision: https://phabricator.services.mozilla.com/D263007 - - - - - 4cf3c86c by Lee Salzman at 2025-09-15T20:12:58+02:00 Bug 1984825. r=jnicol a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D262611 - - - - - 85d7a5cb by Lee Salzman at 2025-09-15T20:13:42+02:00 Bug 1985067. r=jnicol a=RyanVM Differential Revision: https://phabricator.services.mozilla.com/D262614 - - - - - df081c6c by Lee Salzman at 2025-09-15T20:39:59+02:00 Bug 1986185. r=aosmond a=RyanVM Backported manually to 128esr, see BB 44199 Differential Revision: https://phabricator.services.mozilla.com/D263287 - - - - - 12 changed files: - browser/locales/en-US/browser/webrtcIndicator.ftl - browser/modules/webrtcUI.sys.mjs - dom/canvas/WebGLContext.cpp - dom/security/nsContentSecurityManager.cpp - gfx/2d/FilterProcessingScalar.cpp - gfx/2d/InlineTranslator.h - gfx/layers/ipc/CanvasTranslator.cpp - js/src/gc/Statistics.cpp - layout/printing/PrintTranslator.h - mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IntentUtils.java - modules/libpref/init/StaticPrefList.yaml - security/sandbox/linux/launch/SandboxLaunch.cpp Changes: ===================================== browser/locales/en-US/browser/webrtcIndicator.ftl ===================================== @@ -60,7 +60,7 @@ webrtc-screen-system-menu = ## These strings are only used on Mac for menus attached to icons ## near the clock on the mac menubar. ## Variables: -## $streamTitle (String): the title of the tab using the share. +## $streamTitle (String): the host of the tab using the share. ## $tabCount (Number): the title of the tab using the share. webrtc-indicator-menuitem-control-sharing = ===================================== browser/modules/webrtcUI.sys.mjs ===================================== @@ -1048,8 +1048,10 @@ export function showStreamSharingMenu(win, event, inclWindow = false) { let stream = activeStreams[0]; const sharingItem = doc.createXULElement("menuitem"); - const streamTitle = stream.browser.contentTitle || stream.uri; - doc.l10n.setAttributes(sharingItem, l10nIds[0], { streamTitle }); + const displayHost = getDisplayHostForStream(stream); + doc.l10n.setAttributes(sharingItem, l10nIds[0], { + streamTitle: displayHost, + }); sharingItem.setAttribute("disabled", "true"); menu.appendChild(sharingItem); @@ -1073,11 +1075,11 @@ export function showStreamSharingMenu(win, event, inclWindow = false) { for (let stream of activeStreams) { const controlItem = doc.createXULElement("menuitem"); - const streamTitle = stream.browser.contentTitle || stream.uri; + const displayHost = getDisplayHostForStream(stream); doc.l10n.setAttributes( controlItem, "webrtc-indicator-menuitem-control-sharing-on", - { streamTitle } + { streamTitle: displayHost } ); controlItem.stream = stream; controlItem.addEventListener("command", this); @@ -1086,6 +1088,25 @@ export function showStreamSharingMenu(win, event, inclWindow = false) { } } +function getDisplayHostForStream(stream) { + let uri = Services.io.newURI(stream.uri); + + let displayHost; + + try { + displayHost = uri.displayHost; + } catch (ex) { + displayHost = null; + } + + // Host getter threw or returned "". Fall back to spec. + if (displayHost == null || displayHost == "") { + displayHost = uri.displaySpec; + } + + return displayHost; +} + function onTabSharingMenuPopupShowing(e) { const streams = webrtcUI.getActiveStreams(true, true, true, true); for (let streamInfo of streams) { ===================================== dom/canvas/WebGLContext.cpp ===================================== @@ -7,8 +7,9 @@ #include <algorithm> #include <bitset> +#include <cctype> +#include <iterator> #include <queue> -#include <regex> #include "AccessCheck.h" #include "CompositableHost.h" @@ -2204,30 +2205,59 @@ Maybe<std::string> WebGLContext::GetString(const GLenum pname) const { // --------------------------------- Maybe<webgl::IndexedName> webgl::ParseIndexed(const std::string& str) { - static const std::regex kRegex("(.*)\\[([0-9]+)\\]"); - - std::smatch match; - if (!std::regex_match(str, match, kRegex)) return {}; + // Check if the string ends with a close bracket + if (str.size() < 2 || str.back() != ']') { + return {}; + } + // Search for the open bracket, only allow digits between brackets + const size_t closeBracket = str.size() - 1; + size_t openBracket = closeBracket; + for (;;) { + char c = str[--openBracket]; + if (isdigit(c)) { + if (openBracket <= 0) { + // At the beginning of string without an open bracket + return {}; + } + } else if (c == '[') { + // Found the open bracket + break; + } else { + // Found a non-digit + return {}; + } + } - const auto index = std::stoull(match[2]); - return Some(webgl::IndexedName{match[1], index}); + // Ensure non-empty digit sequence + size_t firstDigit = openBracket + 1; + if (firstDigit >= closeBracket) { + return {}; + } + const auto index = + std::stoull(str.substr(firstDigit, closeBracket - firstDigit)); + std::string name = str.substr(0, openBracket); + return Some(webgl::IndexedName{name, index}); } // ExplodeName("foo.bar[3].x") -> ["foo", ".", "bar", "[", "3", "]", ".", "x"] static std::vector<std::string> ExplodeName(const std::string& str) { std::vector<std::string> ret; - - static const std::regex kSep("[.[\\]]"); - - auto itr = std::regex_token_iterator<decltype(str.begin())>( - str.begin(), str.end(), kSep, {-1, 0}); - const auto end = decltype(itr)(); - - for (; itr != end; ++itr) { - const auto& part = itr->str(); - if (part.size()) { - ret.push_back(part); + size_t curPos = 0; + while (curPos < str.size()) { + // Find the next separator + size_t nextPos = str.find_first_of(".[]", curPos); + if (nextPos == std::string::npos) { + // If no separator found, add remaining substring + ret.push_back(str.substr(curPos)); + break; + } + // Add string between separators, if not empty + if (curPos < nextPos) { + ret.push_back(str.substr(curPos, nextPos - curPos)); } + // Add the separator + ret.push_back(str.substr(nextPos, 1)); + curPos = nextPos + 1; } return ret; } ===================================== dom/security/nsContentSecurityManager.cpp ===================================== @@ -45,6 +45,7 @@ #include "mozilla/Logging.h" #include "mozilla/Maybe.h" #include "mozilla/Preferences.h" +#include "mozilla/StaticPrefs_content.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_security.h" #include "mozilla/Telemetry.h" @@ -364,10 +365,17 @@ static nsresult DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo, return NS_OK; } - // We use the triggering principal here, rather than the loading principal - // to ensure that anonymous CORS content in the browser resources and in - // WebExtensions is allowed to load. - nsIPrincipal* principal = aLoadInfo->TriggeringPrincipal(); + nsIPrincipal* principal = aLoadInfo->GetLoadingPrincipal(); + if (StaticPrefs::content_cors_use_triggering_principal()) { + // We use the triggering principal here, rather than the loading principal, + // to ensure that WebExtensions can reuse their own resources from content + // that they inject into a page. + // + // TODO(dholbert): Is there actually a legitimate reason that WebExtensions + // might need this (as opposed to exposing their resources for use in + // web-content via the 'web_accessible_resources' manifest field)? + principal = aLoadInfo->TriggeringPrincipal(); + } RefPtr<nsCORSListenerProxy> corsListener = new nsCORSListenerProxy( aInAndOutListener, principal, aLoadInfo->GetCookiePolicy() == nsILoadInfo::SEC_COOKIES_INCLUDE); ===================================== gfx/2d/FilterProcessingScalar.cpp ===================================== @@ -47,12 +47,12 @@ static void ApplyMorphologyHorizontal_Scalar( x++, startX++, endX++) { int32_t sourceIndex = y * aSourceStride + 4 * startX; uint8_t u[4]; - for (size_t i = 0; i < 4; i++) { + for (int32_t i = 0; i < int32_t(std::size(u)); i++) { u[i] = aSourceData[sourceIndex + i]; } sourceIndex += 4; for (int32_t ix = startX + 1; ix <= endX; ix++, sourceIndex += 4) { - for (size_t i = 0; i < 4; i++) { + for (int32_t i = 0; i < int32_t(std::size(u)); i++) { if (Operator == MORPHOLOGY_OPERATOR_ERODE) { u[i] = umin(u[i], aSourceData[sourceIndex + i]); } else { @@ -62,7 +62,7 @@ static void ApplyMorphologyHorizontal_Scalar( } int32_t destIndex = y * aDestStride + 4 * x; - for (size_t i = 0; i < 4; i++) { + for (int32_t i = 0; i < int32_t(std::size(u)); i++) { aDestData[destIndex + i] = u[i]; } } @@ -97,13 +97,13 @@ static void ApplyMorphologyVertical_Scalar( for (int32_t x = aDestRect.X(); x < aDestRect.XMost(); x++) { int32_t sourceIndex = startY * aSourceStride + 4 * x; uint8_t u[4]; - for (size_t i = 0; i < 4; i++) { + for (int32_t i = 0; i < int32_t(std::size(u)); i++) { u[i] = aSourceData[sourceIndex + i]; } sourceIndex += aSourceStride; for (int32_t iy = startY + 1; iy <= endY; iy++, sourceIndex += aSourceStride) { - for (size_t i = 0; i < 4; i++) { + for (int32_t i = 0; i < int32_t(std::size(u)); i++) { if (Operator == MORPHOLOGY_OPERATOR_ERODE) { u[i] = umin(u[i], aSourceData[sourceIndex + i]); } else { @@ -113,7 +113,7 @@ static void ApplyMorphologyVertical_Scalar( } int32_t destIndex = y * aDestStride + 4 * x; - for (size_t i = 0; i < 4; i++) { + for (int32_t i = 0; i < int32_t(std::size(u)); i++) { aDestData[destIndex + i] = u[i]; } } ===================================== gfx/2d/InlineTranslator.h ===================================== @@ -92,7 +92,11 @@ class InlineTranslator : public Translator { already_AddRefed<SourceSurface> LookupExternalSurface(uint64_t aKey) override; void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget* aDT) final { - mDrawTargets.InsertOrUpdate(aRefPtr, RefPtr{aDT}); + RefPtr<DrawTarget>& value = mDrawTargets.LookupOrInsert(aRefPtr); + if (mCurrentDT && mCurrentDT == value) { + mCurrentDT = nullptr; + } + value = aDT; } void AddPath(ReferencePtr aRefPtr, Path* aPath) final { ===================================== gfx/layers/ipc/CanvasTranslator.cpp ===================================== @@ -189,6 +189,10 @@ mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator( } // Use the first buffer as our current buffer. + if (aBufferHandles.IsEmpty()) { + Deactivate(); + return IPC_FAIL(this, "No canvas buffer shared memory supplied."); + } mDefaultBufferSize = aBufferSize; auto handleIter = aBufferHandles.begin(); if (!CreateAndMapShmem(mCurrentShmem.shmem, std::move(*handleIter), @@ -365,11 +369,19 @@ void CanvasTranslator::GetDataSurface(uint64_t aSurfaceRef) { } void CanvasTranslator::RecycleBuffer() { + if (!mCurrentShmem.IsValid()) { + return; + } + mCanvasShmems.emplace(std::move(mCurrentShmem)); NextBuffer(); } void CanvasTranslator::NextBuffer() { + if (mCanvasShmems.empty()) { + return; + } + // Check and signal the writer when we finish with a buffer, because it // might have hit the buffer count limit and be waiting to use our old one. CheckAndSignalWriter(); ===================================== js/src/gc/Statistics.cpp ===================================== @@ -1518,7 +1518,7 @@ void Statistics::recordParallelPhase(PhaseKind phaseKind, TimeDuration duration) { MOZ_ASSERT(CurrentThreadCanAccessRuntime(gc->rt)); - if (aborted) { + if (slices_.empty()) { return; } ===================================== layout/printing/PrintTranslator.h ===================================== @@ -85,7 +85,11 @@ class PrintTranslator final : public Translator { } void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget* aDT) final { - mDrawTargets.InsertOrUpdate(aRefPtr, RefPtr{aDT}); + RefPtr<DrawTarget>& value = mDrawTargets.LookupOrInsert(aRefPtr); + if (mCurrentDT && mCurrentDT == value) { + mCurrentDT = nullptr; + } + value = aDT; } void AddPath(ReferencePtr aRefPtr, Path* aPath) final { @@ -119,11 +123,11 @@ class PrintTranslator final : public Translator { } void RemoveDrawTarget(ReferencePtr aRefPtr) final { - ReferencePtr currentDT = mCurrentDT; - if (currentDT == aRefPtr) { + RefPtr<DrawTarget> removedDT; + if (mDrawTargets.Remove(aRefPtr, getter_AddRefs(removedDT)) && + mCurrentDT == removedDT) { mCurrentDT = nullptr; } - mDrawTargets.Remove(aRefPtr); } bool SetCurrentDrawTarget(ReferencePtr aRefPtr) final { ===================================== mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IntentUtils.java ===================================== @@ -72,7 +72,7 @@ public class IntentUtils { } if (("intent".equals(scheme) || "android-app".equals(scheme))) { - // Bug 1356893 - Rject intents with file data schemes. + // Bug 1356893 - Reject intents with file data schemes. return getSafeIntent(aUri) != null; } @@ -98,8 +98,11 @@ public class IntentUtils { } final Uri data = intent.getData(); - if (data != null && "file".equals(normalizeUriScheme(data).getScheme())) { - return null; + if (data != null) { + final String scheme = normalizeUriScheme(data).getScheme(); + if ("file".equals(scheme) || "fido".equals(scheme)) { + return null; + } } // Only open applications which can accept arbitrary data from a browser. ===================================== modules/libpref/init/StaticPrefList.yaml ===================================== @@ -1961,6 +1961,14 @@ value: false mirror: always +# If true, we'll use the triggering principal rather than the loading principal +# when doing CORS checks. This might be needed for WebExtensions to load their +# own resources from content that they inject into sites. +- name: content.cors.use_triggering_principal + type: bool + value: false + mirror: always + # Back off timer notification after count. # -1 means never. - name: content.notify.backoffcount ===================================== security/sandbox/linux/launch/SandboxLaunch.cpp ===================================== @@ -304,6 +304,8 @@ void SandboxLaunch::Configure(GeckoProcessType aType, SandboxingKind aKind, return; } + // Warning: don't combine multiple case labels, even if the code is + // currently the same, to avoid mistakes when changes are made. switch (aType) { case GeckoProcessType_Socket: if (level >= 1) { @@ -312,6 +314,12 @@ void SandboxLaunch::Configure(GeckoProcessType aType, SandboxingKind aKind, } break; case GeckoProcessType_GMPlugin: + if (level >= 1) { + canChroot = true; + flags |= CLONE_NEWIPC; + flags |= CLONE_NEWNET; + } + break; case GeckoProcessType_RDD: if (level >= 1) { canChroot = true; View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/59baa99... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/59baa99... You're receiving this email because of your account on gitlab.torproject.org.