morgan pushed to branch base-browser-128.11.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
67609f51
by smayya at 2025-05-26T20:22:49+00:00
-
9135b49b
by hackademix at 2025-05-26T20:22:49+00:00
-
3863a3bb
by Oskar Mansfeld at 2025-05-26T20:22:49+00:00
-
23aa8fbb
by Daniel Holbert at 2025-05-26T20:22:50+00:00
-
a75f2376
by Daniel Holbert at 2025-05-26T20:22:50+00:00
-
ab86560a
by Daniel Holbert at 2025-05-26T20:22:50+00:00
-
5ae92208
by Gijs Kruitbosch at 2025-05-26T20:22:51+00:00
15 changed files:
- browser/app/profile/001-base-profile.js
- dom/svg/DOMSVGLength.cpp
- dom/svg/DOMSVGLength.h
- dom/svg/DOMSVGPoint.cpp
- dom/svg/DOMSVGPoint.h
- dom/svg/DOMSVGPointList.cpp
- dom/svg/DOMSVGPointList.h
- dom/svg/DOMSVGStringList.cpp
- dom/svg/DOMSVGStringList.h
- modules/libpref/init/StaticPrefList.yaml
- netwerk/base/nsIOService.cpp
- netwerk/base/nsSocketTransport2.cpp
- netwerk/protocol/http/HttpConnectionUDP.cpp
- netwerk/test/unit/trr_common.js
- toolkit/components/aboutmemory/content/aboutMemory.js
Changes:
... | ... | @@ -536,6 +536,11 @@ pref("network.proxy.failover_direct", false, locked); |
536 | 536 | // alters content load order in a page. See tor-browser#24686
|
537 | 537 | pref("network.http.tailing.enabled", true, locked);
|
538 | 538 | |
539 | +// Block 0.0.0.0
|
|
540 | +// https://bugzilla.mozilla.org/show_bug.cgi?id=1889130
|
|
541 | +// tor-browser#43811
|
|
542 | +pref("network.socket.ip_addr_any.disabled", true);
|
|
543 | + |
|
539 | 544 | // tor-browser#23044: Make sure we don't have any GIO supported protocols
|
540 | 545 | // (defense in depth measure).
|
541 | 546 | // As of Firefox 118 (Bug 1843763), upstream does not add any protocol by
|
... | ... | @@ -51,6 +51,7 @@ DOMSVGLength::DOMSVGLength(DOMSVGLengthList* aList, uint8_t aAttrEnum, |
51 | 51 | mListIndex(aListIndex),
|
52 | 52 | mAttrEnum(aAttrEnum),
|
53 | 53 | mIsAnimValItem(aIsAnimValItem),
|
54 | + mIsInTearoffTable(false),
|
|
54 | 55 | mUnit(SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {
|
55 | 56 | MOZ_ASSERT(aList, "bad arg");
|
56 | 57 | MOZ_ASSERT(mAttrEnum == aAttrEnum, "bitfield too small");
|
... | ... | @@ -63,6 +64,7 @@ DOMSVGLength::DOMSVGLength() |
63 | 64 | mListIndex(0),
|
64 | 65 | mAttrEnum(0),
|
65 | 66 | mIsAnimValItem(false),
|
67 | + mIsInTearoffTable(false),
|
|
66 | 68 | mUnit(SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {}
|
67 | 69 | |
68 | 70 | DOMSVGLength::DOMSVGLength(SVGAnimatedLength* aVal, SVGElement* aSVGElement,
|
... | ... | @@ -71,6 +73,7 @@ DOMSVGLength::DOMSVGLength(SVGAnimatedLength* aVal, SVGElement* aSVGElement, |
71 | 73 | mListIndex(0),
|
72 | 74 | mAttrEnum(aVal->mAttrEnum),
|
73 | 75 | mIsAnimValItem(aAnimVal),
|
76 | + mIsInTearoffTable(false),
|
|
74 | 77 | mUnit(SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) {
|
75 | 78 | MOZ_ASSERT(aVal, "bad arg");
|
76 | 79 | MOZ_ASSERT(mAttrEnum == aVal->mAttrEnum, "bitfield too small");
|
... | ... | @@ -88,22 +91,33 @@ void DOMSVGLength::CleanupWeakRefs() { |
88 | 91 | |
89 | 92 | // Similarly, we must update the tearoff table to remove its (non-owning)
|
90 | 93 | // pointer to mVal.
|
91 | - if (nsCOMPtr<SVGElement> svg = do_QueryInterface(mOwner)) {
|
|
92 | - auto& table = mIsAnimValItem ? sAnimSVGLengthTearOffTable
|
|
93 | - : sBaseSVGLengthTearOffTable;
|
|
94 | - table.RemoveTearoff(svg->GetAnimatedLength(mAttrEnum));
|
|
94 | + if (mIsInTearoffTable) {
|
|
95 | + nsCOMPtr<SVGElement> svg = do_QueryInterface(mOwner);
|
|
96 | + MOZ_ASSERT(svg,
|
|
97 | + "We need our svgElement reference in order to remove "
|
|
98 | + "ourselves from tearoff table...");
|
|
99 | + if (MOZ_LIKELY(svg)) {
|
|
100 | + auto& table = mIsAnimValItem ? sAnimSVGLengthTearOffTable
|
|
101 | + : sBaseSVGLengthTearOffTable;
|
|
102 | + table.RemoveTearoff(svg->GetAnimatedLength(mAttrEnum));
|
|
103 | + mIsInTearoffTable = false;
|
|
104 | + }
|
|
95 | 105 | }
|
96 | 106 | }
|
97 | 107 | |
98 | 108 | already_AddRefed<DOMSVGLength> DOMSVGLength::GetTearOff(SVGAnimatedLength* aVal,
|
99 | 109 | SVGElement* aSVGElement,
|
100 | 110 | bool aAnimVal) {
|
111 | + MOZ_ASSERT(aVal && aSVGElement, "Expecting non-null aVal and aSVGElement");
|
|
112 | + MOZ_ASSERT(aVal == aSVGElement->GetAnimatedLength(aVal->mAttrEnum),
|
|
113 | + "Mismatched aVal/SVGElement?");
|
|
101 | 114 | auto& table =
|
102 | 115 | aAnimVal ? sAnimSVGLengthTearOffTable : sBaseSVGLengthTearOffTable;
|
103 | 116 | RefPtr<DOMSVGLength> domLength = table.GetTearoff(aVal);
|
104 | 117 | if (!domLength) {
|
105 | 118 | domLength = new DOMSVGLength(aVal, aSVGElement, aAnimVal);
|
106 | 119 | table.AddTearoff(aVal, domLength);
|
120 | + domLength->mIsInTearoffTable = true;
|
|
107 | 121 | }
|
108 | 122 | |
109 | 123 | return domLength.forget();
|
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | #include "mozilla/Attributes.h"
|
16 | 16 | #include "nsWrapperCache.h"
|
17 | 17 | |
18 | -#define MOZ_SVG_LIST_INDEX_BIT_COUNT 22 // supports > 4 million list items
|
|
18 | +#define MOZ_SVG_LIST_INDEX_BIT_COUNT 21 // supports > 2 million list items
|
|
19 | 19 | |
20 | 20 | namespace mozilla {
|
21 | 21 | |
... | ... | @@ -204,6 +204,13 @@ class DOMSVGLength final : public nsWrapperCache { |
204 | 204 | uint32_t mAttrEnum : 4; // supports up to 16 attributes
|
205 | 205 | uint32_t mIsAnimValItem : 1;
|
206 | 206 | |
207 | + // Tracks whether we're in the tearoff table. Initialized to false in the
|
|
208 | + // ctor, but then immediately set to true after we're added to the table
|
|
209 | + // (unless we're an instance created via 'Copy()'; those never get added to
|
|
210 | + // the table). Updated to false when we're removed from the table (at which
|
|
211 | + // point we're being destructed or soon-to-be destructed).
|
|
212 | + uint32_t mIsInTearoffTable : 1;
|
|
213 | + |
|
207 | 214 | // The following members are only used when we're not in a list:
|
208 | 215 | uint32_t mUnit : 5; // can handle 31 units (the 10 SVG 1.1 units + rem, vw,
|
209 | 216 | // vh, wm, calc + future additions)
|
... | ... | @@ -167,6 +167,7 @@ already_AddRefed<DOMSVGPoint> DOMSVGPoint::GetTranslateTearOff( |
167 | 167 | if (!domPoint) {
|
168 | 168 | domPoint = new DOMSVGPoint(aVal, aSVGSVGElement);
|
169 | 169 | sSVGTranslateTearOffTable.AddTearoff(aVal, domPoint);
|
170 | + domPoint->mIsInTearoffTable = true;
|
|
170 | 171 | }
|
171 | 172 | |
172 | 173 | return domPoint.forget();
|
... | ... | @@ -203,12 +204,18 @@ void DOMSVGPoint::CleanupWeakRefs() { |
203 | 204 | pointList->mItems[mListIndex] = nullptr;
|
204 | 205 | }
|
205 | 206 | |
207 | + if (mIsInTearoffTable) {
|
|
208 | + // Similarly, we must update the tearoff table to remove its (non-owning)
|
|
209 | + // pointer to mVal.
|
|
210 | + MOZ_ASSERT(mVal && mIsTranslatePoint,
|
|
211 | + "Tearoff table should only be used for translate-point objects "
|
|
212 | + "with non-null mVal (see GetTranslateTearOff and its callers)");
|
|
213 | + sSVGTranslateTearOffTable.RemoveTearoff(mVal);
|
|
214 | + mIsInTearoffTable = false;
|
|
215 | + }
|
|
216 | + |
|
206 | 217 | if (mVal) {
|
207 | - if (mIsTranslatePoint) {
|
|
208 | - // Similarly, we must update the tearoff table to remove its (non-owning)
|
|
209 | - // pointer to mVal.
|
|
210 | - sSVGTranslateTearOffTable.RemoveTearoff(mVal);
|
|
211 | - } else {
|
|
218 | + if (!mIsTranslatePoint) {
|
|
212 | 219 | // In this case we own mVal
|
213 | 220 | delete mVal;
|
214 | 221 | }
|
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | #include "mozilla/dom/SVGSVGElement.h"
|
18 | 18 | #include "mozilla/gfx/2D.h"
|
19 | 19 | |
20 | -#define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
|
|
20 | +#define MOZ_SVG_LIST_INDEX_BIT_COUNT 29
|
|
21 | 21 | |
22 | 22 | namespace mozilla::dom {
|
23 | 23 | struct DOMMatrix2DInit;
|
... | ... | @@ -51,7 +51,8 @@ class DOMSVGPoint final : public nsWrapperCache { |
51 | 51 | mOwner(aList),
|
52 | 52 | mListIndex(aListIndex),
|
53 | 53 | mIsAnimValItem(aIsAnimValItem),
|
54 | - mIsTranslatePoint(false) {
|
|
54 | + mIsTranslatePoint(false),
|
|
55 | + mIsInTearoffTable(false) {
|
|
55 | 56 | // These shifts are in sync with the members.
|
56 | 57 | MOZ_ASSERT(aList && aListIndex <= MaxListIndex(), "bad arg");
|
57 | 58 | |
... | ... | @@ -60,7 +61,10 @@ class DOMSVGPoint final : public nsWrapperCache { |
60 | 61 | |
61 | 62 | // Constructor for unowned points and SVGSVGElement.createSVGPoint
|
62 | 63 | explicit DOMSVGPoint(const Point& aPt)
|
63 | - : mListIndex(0), mIsAnimValItem(false), mIsTranslatePoint(false) {
|
|
64 | + : mListIndex(0),
|
|
65 | + mIsAnimValItem(false),
|
|
66 | + mIsTranslatePoint(false),
|
|
67 | + mIsInTearoffTable(false) {
|
|
64 | 68 | // In this case we own mVal
|
65 | 69 | mVal = new SVGPoint(aPt.x, aPt.y);
|
66 | 70 | }
|
... | ... | @@ -72,7 +76,8 @@ class DOMSVGPoint final : public nsWrapperCache { |
72 | 76 | mOwner(ToSupports(aSVGSVGElement)),
|
73 | 77 | mListIndex(0),
|
74 | 78 | mIsAnimValItem(false),
|
75 | - mIsTranslatePoint(true) {}
|
|
79 | + mIsTranslatePoint(true),
|
|
80 | + mIsInTearoffTable(false) {}
|
|
76 | 81 | |
77 | 82 | virtual ~DOMSVGPoint() { CleanupWeakRefs(); }
|
78 | 83 | |
... | ... | @@ -178,6 +183,12 @@ class DOMSVGPoint final : public nsWrapperCache { |
178 | 183 | uint32_t mListIndex : MOZ_SVG_LIST_INDEX_BIT_COUNT;
|
179 | 184 | uint32_t mIsAnimValItem : 1; // True if We're the animated value of a list
|
180 | 185 | uint32_t mIsTranslatePoint : 1; // true iff our owner is a SVGSVGElement
|
186 | + |
|
187 | + // Tracks whether we're in the tearoff table. Initialized to false in the
|
|
188 | + // ctor, but then immediately set to true if/when we're added to the table
|
|
189 | + // (not all instances are). Updated to false when we're removed from the
|
|
190 | + // table (at which point we're being destructed or soon-to-be destructed).
|
|
191 | + uint32_t mIsInTearoffTable : 1;
|
|
181 | 192 | };
|
182 | 193 | |
183 | 194 | } // namespace mozilla::dom
|
... | ... | @@ -90,9 +90,12 @@ void DOMSVGPointList::RemoveFromTearoffTable() { |
90 | 90 | //
|
91 | 91 | // There are now no longer any references to us held by script or list items.
|
92 | 92 | // Note we must use GetAnimValKey/GetBaseValKey here, NOT InternalList()!
|
93 | - void* key = mIsAnimValList ? InternalAList().GetAnimValKey()
|
|
94 | - : InternalAList().GetBaseValKey();
|
|
95 | - SVGPointListTearoffTable().RemoveTearoff(key);
|
|
93 | + if (mIsInTearoffTable) {
|
|
94 | + void* key = mIsAnimValList ? InternalAList().GetAnimValKey()
|
|
95 | + : InternalAList().GetBaseValKey();
|
|
96 | + SVGPointListTearoffTable().RemoveTearoff(key);
|
|
97 | + mIsInTearoffTable = false;
|
|
98 | + }
|
|
96 | 99 | }
|
97 | 100 | |
98 | 101 | DOMSVGPointList::~DOMSVGPointList() { RemoveFromTearoffTable(); }
|
... | ... | @@ -251,6 +251,12 @@ class DOMSVGPointList final : public nsISupports, public nsWrapperCache { |
251 | 251 | RefPtr<dom::SVGElement> mElement;
|
252 | 252 | |
253 | 253 | bool mIsAnimValList;
|
254 | + |
|
255 | + // Tracks whether we're in the tearoff table. Initialized to true, since all
|
|
256 | + // new instances are added to the table right after construction. Updated to
|
|
257 | + // false when we're removed from the table (at which point we're being
|
|
258 | + // destructed or soon-to-be destructed).
|
|
259 | + bool mIsInTearoffTable = true;
|
|
254 | 260 | };
|
255 | 261 | |
256 | 262 | NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGPointList, MOZILLA_DOMSVGPOINTLIST_IID)
|
... | ... | @@ -91,7 +91,10 @@ already_AddRefed<DOMSVGStringList> DOMSVGStringList::GetDOMWrapper( |
91 | 91 | |
92 | 92 | void DOMSVGStringList::RemoveFromTearoffTable() {
|
93 | 93 | // Script no longer has any references to us.
|
94 | - SVGStringListTearoffTable().RemoveTearoff(&InternalList());
|
|
94 | + if (mIsInTearoffTable) {
|
|
95 | + SVGStringListTearoffTable().RemoveTearoff(&InternalList());
|
|
96 | + mIsInTearoffTable = false;
|
|
97 | + }
|
|
95 | 98 | }
|
96 | 99 | |
97 | 100 | DOMSVGStringList::~DOMSVGStringList() { RemoveFromTearoffTable(); }
|
... | ... | @@ -108,6 +108,12 @@ class DOMSVGStringList final : public nsISupports, public nsWrapperCache { |
108 | 108 | uint8_t mAttrEnum;
|
109 | 109 | |
110 | 110 | bool mIsConditionalProcessingAttribute;
|
111 | + |
|
112 | + // Tracks whether we're in the tearoff table. Initialized to true, since all
|
|
113 | + // new instances are added to the table right after construction. Updated to
|
|
114 | + // false when we're removed from the table (at which point we're being
|
|
115 | + // destructed or soon-to-be destructed).
|
|
116 | + bool mIsInTearoffTable = true;
|
|
111 | 117 | };
|
112 | 118 | |
113 | 119 | } // namespace dom
|
... | ... | @@ -12175,6 +12175,13 @@ |
12175 | 12175 | value: true
|
12176 | 12176 | mirror: always
|
12177 | 12177 | |
12178 | +# Disable requests to 0.0.0.0
|
|
12179 | +# See Bug 1889130
|
|
12180 | +- name: network.socket.ip_addr_any.disabled
|
|
12181 | + type: RelaxedAtomicBool
|
|
12182 | + value: @IS_EARLY_BETA_OR_EARLIER@
|
|
12183 | + mirror: always
|
|
12184 | + |
|
12178 | 12185 | # Set true to allow resolving proxy for localhost
|
12179 | 12186 | - name: network.proxy.allow_hijacking_localhost
|
12180 | 12187 | type: RelaxedAtomicBool
|
... | ... | @@ -239,6 +239,7 @@ static const char* gCallbackPrefsForSocketProcess[] = { |
239 | 239 | "network.proxy.allow_hijacking_localhost",
|
240 | 240 | "network.connectivity-service.",
|
241 | 241 | "network.captive-portal-service.testMode",
|
242 | + "network.socket.ip_addr_any.disabled",
|
|
242 | 243 | nullptr,
|
243 | 244 | };
|
244 | 245 |
... | ... | @@ -1241,6 +1241,15 @@ nsresult nsSocketTransport::InitiateSocket() { |
1241 | 1241 | if (gIOService->IsNetTearingDown()) {
|
1242 | 1242 | return NS_ERROR_ABORT;
|
1243 | 1243 | }
|
1244 | + |
|
1245 | + // Since https://github.com/whatwg/fetch/pull/1763,
|
|
1246 | + // we need to disable access to 0.0.0.0 for non-test purposes
|
|
1247 | + if (StaticPrefs::network_socket_ip_addr_any_disabled() &&
|
|
1248 | + mNetAddr.IsIPAddrAny() && !mProxyTransparentResolvesHost) {
|
|
1249 | + SOCKET_LOG(("connection refused NS_ERROR_CONNECTION_REFUSED\n"));
|
|
1250 | + return NS_ERROR_CONNECTION_REFUSED;
|
|
1251 | + }
|
|
1252 | + |
|
1244 | 1253 | if (gIOService->IsOffline()) {
|
1245 | 1254 | if (StaticPrefs::network_disable_localhost_when_offline() || !isLocal) {
|
1246 | 1255 | return NS_ERROR_OFFLINE;
|
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | |
20 | 20 | #include "ASpdySession.h"
|
21 | 21 | #include "mozilla/StaticPrefs_network.h"
|
22 | +#include "mozilla/glean/NetwerkMetrics.h"
|
|
22 | 23 | #include "mozilla/Telemetry.h"
|
23 | 24 | #include "HttpConnectionUDP.h"
|
24 | 25 | #include "nsHttpHandler.h"
|
... | ... | @@ -88,6 +89,22 @@ nsresult HttpConnectionUDP::Init(nsHttpConnectionInfo* info, |
88 | 89 | return rv;
|
89 | 90 | }
|
90 | 91 | |
92 | + // We are disabling 0.0.0.0 for non-test purposes.
|
|
93 | + // See https://github.com/whatwg/fetch/pull/1763 for context.
|
|
94 | + if (peerAddr.IsIPAddrAny()) {
|
|
95 | + if (StaticPrefs::network_socket_ip_addr_any_disabled()) {
|
|
96 | + mozilla::glean::networking::http_ip_addr_any_count
|
|
97 | + .Get("blocked_requests"_ns)
|
|
98 | + .Add(1);
|
|
99 | + LOG(("Connection refused because of 0.0.0.0 IP address\n"));
|
|
100 | + return NS_ERROR_CONNECTION_REFUSED;
|
|
101 | + }
|
|
102 | + |
|
103 | + mozilla::glean::networking::http_ip_addr_any_count
|
|
104 | + .Get("not_blocked_requests"_ns)
|
|
105 | + .Add(1);
|
|
106 | + }
|
|
107 | + |
|
91 | 108 | mSocket = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
|
92 | 109 | if (NS_FAILED(rv)) {
|
93 | 110 | return rv;
|
... | ... | @@ -1027,6 +1027,7 @@ async function test_ipv4_trr_fallback() { |
1027 | 1027 | async function test_no_retry_without_doh() {
|
1028 | 1028 | info("Bug 1648147 - if the TRR returns 0.0.0.0 we should not retry with DNS");
|
1029 | 1029 | Services.prefs.setBoolPref("network.trr.fallback-on-zero-response", false);
|
1030 | + Services.prefs.setBoolPref("network.socket.ip_addr_any.disabled", false);
|
|
1030 | 1031 | |
1031 | 1032 | async function test(url, ip) {
|
1032 | 1033 | setModeAndURI(2, `doh?responseIP=${ip}`);
|
... | ... | @@ -1073,6 +1074,8 @@ async function test_no_retry_without_doh() { |
1073 | 1074 | await test(`http://unknown.ipv4.stuff:666/path`, "0.0.0.0");
|
1074 | 1075 | await test(`http://unknown.ipv6.stuff:666/path`, "::");
|
1075 | 1076 | }
|
1077 | + |
|
1078 | + Services.prefs.clearUserPref("network.socket.ip_addr_any.disabled");
|
|
1076 | 1079 | }
|
1077 | 1080 | |
1078 | 1081 | async function test_connection_reuse_and_cycling() {
|
... | ... | @@ -508,19 +508,11 @@ window.onload = function () { |
508 | 508 | appendElementWithText(gFooter, "div", "legend", legendText1);
|
509 | 509 | appendElementWithText(gFooter, "div", "legend hiddenOnMobile", legendText2);
|
510 | 510 | |
511 | - // See if we're loading from a file. (Because about:memory is a non-standard
|
|
512 | - // URL, location.search is undefined, so we have to use location.href
|
|
513 | - // instead.)
|
|
514 | - let search = location.href.split("?")[1];
|
|
515 | - if (search) {
|
|
516 | - let searchSplit = search.split("&");
|
|
517 | - for (let s of searchSplit) {
|
|
518 | - if (s.toLowerCase().startsWith("file=")) {
|
|
519 | - let filename = s.substring("file=".length);
|
|
520 | - updateAboutMemoryFromFile(decodeURIComponent(filename));
|
|
521 | - return;
|
|
522 | - }
|
|
523 | - }
|
|
511 | + // See if we're loading from a file.
|
|
512 | + let { searchParams } = URL.fromURI(document.documentURIObject);
|
|
513 | + let fileParam = searchParams.get("file");
|
|
514 | + if (fileParam) {
|
|
515 | + updateAboutMemoryFromFile(fileParam);
|
|
524 | 516 | }
|
525 | 517 | };
|
526 | 518 |