ma1 pushed to branch tor-browser-115.24.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
0a4acb71
by smayya at 2025-05-22T17:18:56+02:00
-
02ee510f
by hackademix at 2025-05-22T17:34:56+02:00
-
6186c1fe
by Oskar Mansfeld at 2025-05-26T17:25:28+02:00
-
dc06e11d
by Daniel Holbert at 2025-05-26T17:25:48+02:00
-
4f3e5d70
by Daniel Holbert at 2025-05-26T17:25:49+02:00
-
d5a152e4
by Daniel Holbert at 2025-05-26T17:25:50+02:00
-
73753ce8
by Jonathan Kew at 2025-05-26T17:25:50+02:00
-
d3e4fff1
by Gijs Kruitbosch at 2025-05-26T17:25:51+02:00
16 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
- gfx/thebes/gfxFont.cpp
- 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:
... | ... | @@ -482,6 +482,11 @@ pref("network.http.http2.default-hpack-buffer", 65536, locked); |
482 | 482 | pref("network.http.http2.websockets", true, locked);
|
483 | 483 | pref("network.http.http2.enable-hpack-dump", false, locked);
|
484 | 484 | |
485 | +// Block 0.0.0.0
|
|
486 | +// https://bugzilla.mozilla.org/show_bug.cgi?id=1889130
|
|
487 | +// tor-browser#43811
|
|
488 | +pref("network.socket.ip_addr_any.disabled", true);
|
|
489 | + |
|
485 | 490 | // tor-browser#23044: Make sure we don't have any GIO supported protocols
|
486 | 491 | // (defense in depth measure)
|
487 | 492 | pref("network.gio.supported-protocols", "");
|
... | ... | @@ -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 | |
... | ... | @@ -198,6 +198,13 @@ class DOMSVGLength final : public nsWrapperCache { |
198 | 198 | uint32_t mAttrEnum : 4; // supports up to 16 attributes
|
199 | 199 | uint32_t mIsAnimValItem : 1;
|
200 | 200 | |
201 | + // Tracks whether we're in the tearoff table. Initialized to false in the
|
|
202 | + // ctor, but then immediately set to true after we're added to the table
|
|
203 | + // (unless we're an instance created via 'Copy()'; those never get added to
|
|
204 | + // the table). Updated to false when we're removed from the table (at which
|
|
205 | + // point we're being destructed or soon-to-be destructed).
|
|
206 | + uint32_t mIsInTearoffTable : 1;
|
|
207 | + |
|
201 | 208 | // The following members are only used when we're not in a list:
|
202 | 209 | uint32_t mUnit : 5; // can handle 31 units (the 10 SVG 1.1 units + rem, vw,
|
203 | 210 | // vh, wm, calc + future additions)
|
... | ... | @@ -168,6 +168,7 @@ already_AddRefed<DOMSVGPoint> DOMSVGPoint::GetTranslateTearOff( |
168 | 168 | if (!domPoint) {
|
169 | 169 | domPoint = new DOMSVGPoint(aVal, aSVGSVGElement);
|
170 | 170 | sSVGTranslateTearOffTable.AddTearoff(aVal, domPoint);
|
171 | + domPoint->mIsInTearoffTable = true;
|
|
171 | 172 | }
|
172 | 173 | |
173 | 174 | return domPoint.forget();
|
... | ... | @@ -204,12 +205,18 @@ void DOMSVGPoint::CleanupWeakRefs() { |
204 | 205 | pointList->mItems[mListIndex] = nullptr;
|
205 | 206 | }
|
206 | 207 | |
208 | + if (mIsInTearoffTable) {
|
|
209 | + // Similarly, we must update the tearoff table to remove its (non-owning)
|
|
210 | + // pointer to mVal.
|
|
211 | + MOZ_ASSERT(mVal && mIsTranslatePoint,
|
|
212 | + "Tearoff table should only be used for translate-point objects "
|
|
213 | + "with non-null mVal (see GetTranslateTearOff and its callers)");
|
|
214 | + sSVGTranslateTearOffTable.RemoveTearoff(mVal);
|
|
215 | + mIsInTearoffTable = false;
|
|
216 | + }
|
|
217 | + |
|
207 | 218 | if (mVal) {
|
208 | - if (mIsTranslatePoint) {
|
|
209 | - // Similarly, we must update the tearoff table to remove its (non-owning)
|
|
210 | - // pointer to mVal.
|
|
211 | - sSVGTranslateTearOffTable.RemoveTearoff(mVal);
|
|
212 | - } else {
|
|
219 | + if (!mIsTranslatePoint) {
|
|
213 | 220 | // In this case we own mVal
|
214 | 221 | delete mVal;
|
215 | 222 | }
|
... | ... | @@ -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
|
... | ... | @@ -88,9 +88,12 @@ void DOMSVGPointList::RemoveFromTearoffTable() { |
88 | 88 | //
|
89 | 89 | // There are now no longer any references to us held by script or list items.
|
90 | 90 | // Note we must use GetAnimValKey/GetBaseValKey here, NOT InternalList()!
|
91 | - void* key = mIsAnimValList ? InternalAList().GetAnimValKey()
|
|
92 | - : InternalAList().GetBaseValKey();
|
|
93 | - SVGPointListTearoffTable().RemoveTearoff(key);
|
|
91 | + if (mIsInTearoffTable) {
|
|
92 | + void* key = mIsAnimValList ? InternalAList().GetAnimValKey()
|
|
93 | + : InternalAList().GetBaseValKey();
|
|
94 | + SVGPointListTearoffTable().RemoveTearoff(key);
|
|
95 | + mIsInTearoffTable = false;
|
|
96 | + }
|
|
94 | 97 | }
|
95 | 98 | |
96 | 99 | DOMSVGPointList::~DOMSVGPointList() { RemoveFromTearoffTable(); }
|
... | ... | @@ -250,6 +250,12 @@ class DOMSVGPointList final : public nsISupports, public nsWrapperCache { |
250 | 250 | RefPtr<dom::SVGElement> mElement;
|
251 | 251 | |
252 | 252 | bool mIsAnimValList;
|
253 | + |
|
254 | + // Tracks whether we're in the tearoff table. Initialized to true, since all
|
|
255 | + // new instances are added to the table right after construction. Updated to
|
|
256 | + // false when we're removed from the table (at which point we're being
|
|
257 | + // destructed or soon-to-be destructed).
|
|
258 | + bool mIsInTearoffTable = true;
|
|
253 | 259 | };
|
254 | 260 | |
255 | 261 | 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
|
... | ... | @@ -1293,8 +1293,12 @@ static const hb_tag_t defaultFeatures[] = { |
1293 | 1293 | void gfxFont::CheckForFeaturesInvolvingSpace() const {
|
1294 | 1294 | gfxFontEntry::SpaceFeatures flags = gfxFontEntry::SpaceFeatures::None;
|
1295 | 1295 | |
1296 | + // mFontEntry->mHasSpaceFeatures is a std::atomic<>, so we set it with
|
|
1297 | + // `exchange` to avoid a potential data race. It's ok if two threads both
|
|
1298 | + // try to set it; they'll end up with the same value, so it doesn't matter
|
|
1299 | + // that one will overwrite the other.
|
|
1296 | 1300 | auto setFlags =
|
1297 | - MakeScopeExit([&]() { mFontEntry->mHasSpaceFeatures = flags; });
|
|
1301 | + MakeScopeExit([&]() { mFontEntry->mHasSpaceFeatures.exchange(flags); });
|
|
1298 | 1302 | |
1299 | 1303 | bool log = LOG_FONTINIT_ENABLED();
|
1300 | 1304 | TimeStamp start;
|
... | ... | @@ -11735,6 +11735,13 @@ |
11735 | 11735 | value: true
|
11736 | 11736 | mirror: always
|
11737 | 11737 | |
11738 | +# Disable requests to 0.0.0.0
|
|
11739 | +# See Bug 1889130
|
|
11740 | +- name: network.socket.ip_addr_any.disabled
|
|
11741 | + type: RelaxedAtomicBool
|
|
11742 | + value: @IS_EARLY_BETA_OR_EARLIER@
|
|
11743 | + mirror: always
|
|
11744 | + |
|
11738 | 11745 | # Set true to allow resolving proxy for localhost
|
11739 | 11746 | - name: network.proxy.allow_hijacking_localhost
|
11740 | 11747 | type: RelaxedAtomicBool
|
... | ... | @@ -230,6 +230,7 @@ static const char* gCallbackPrefsForSocketProcess[] = { |
230 | 230 | "network.proxy.allow_hijacking_localhost",
|
231 | 231 | "network.connectivity-service.",
|
232 | 232 | "network.captive-portal-service.testMode",
|
233 | + "network.socket.ip_addr_any.disabled",
|
|
233 | 234 | nullptr,
|
234 | 235 | };
|
235 | 236 |
... | ... | @@ -1245,6 +1245,15 @@ nsresult nsSocketTransport::InitiateSocket() { |
1245 | 1245 | if (gIOService->IsNetTearingDown()) {
|
1246 | 1246 | return NS_ERROR_ABORT;
|
1247 | 1247 | }
|
1248 | + |
|
1249 | + // Since https://github.com/whatwg/fetch/pull/1763,
|
|
1250 | + // we need to disable access to 0.0.0.0 for non-test purposes
|
|
1251 | + if (StaticPrefs::network_socket_ip_addr_any_disabled() &&
|
|
1252 | + mNetAddr.IsIPAddrAny() && !mProxyTransparentResolvesHost) {
|
|
1253 | + SOCKET_LOG(("connection refused NS_ERROR_CONNECTION_REFUSED\n"));
|
|
1254 | + return NS_ERROR_CONNECTION_REFUSED;
|
|
1255 | + }
|
|
1256 | + |
|
1248 | 1257 | if (gIOService->IsOffline()) {
|
1249 | 1258 | if (StaticPrefs::network_disable_localhost_when_offline() || !isLocal) {
|
1250 | 1259 | return NS_ERROR_OFFLINE;
|
... | ... | @@ -86,6 +86,15 @@ nsresult HttpConnectionUDP::Init(nsHttpConnectionInfo* info, |
86 | 86 | return rv;
|
87 | 87 | }
|
88 | 88 | |
89 | + // We are disabling 0.0.0.0 for non-test purposes.
|
|
90 | + // See https://github.com/whatwg/fetch/pull/1763 for context.
|
|
91 | + if (peerAddr.IsIPAddrAny()) {
|
|
92 | + if (StaticPrefs::network_socket_ip_addr_any_disabled()) {
|
|
93 | + LOG(("Connection refused because of 0.0.0.0 IP address\n"));
|
|
94 | + return NS_ERROR_CONNECTION_REFUSED;
|
|
95 | + }
|
|
96 | + }
|
|
97 | + |
|
89 | 98 | mSocket = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
|
90 | 99 | if (NS_FAILED(rv)) {
|
91 | 100 | return rv;
|
... | ... | @@ -1025,6 +1025,7 @@ async function test_ipv4_trr_fallback() { |
1025 | 1025 | async function test_no_retry_without_doh() {
|
1026 | 1026 | info("Bug 1648147 - if the TRR returns 0.0.0.0 we should not retry with DNS");
|
1027 | 1027 | Services.prefs.setBoolPref("network.trr.fallback-on-zero-response", false);
|
1028 | + Services.prefs.setBoolPref("network.socket.ip_addr_any.disabled", false);
|
|
1028 | 1029 | |
1029 | 1030 | async function test(url, ip) {
|
1030 | 1031 | setModeAndURI(2, `doh?responseIP=${ip}`);
|
... | ... | @@ -1071,6 +1072,8 @@ async function test_no_retry_without_doh() { |
1071 | 1072 | await test(`http://unknown.ipv4.stuff:666/path`, "0.0.0.0");
|
1072 | 1073 | await test(`http://unknown.ipv6.stuff:666/path`, "::");
|
1073 | 1074 | }
|
1075 | + |
|
1076 | + Services.prefs.clearUserPref("network.socket.ip_addr_any.disabled");
|
|
1074 | 1077 | }
|
1075 | 1078 | |
1076 | 1079 | async function test_connection_reuse_and_cycling() {
|
... | ... | @@ -506,19 +506,11 @@ window.onload = function () { |
506 | 506 | appendElementWithText(gFooter, "div", "legend", legendText1);
|
507 | 507 | appendElementWithText(gFooter, "div", "legend hiddenOnMobile", legendText2);
|
508 | 508 | |
509 | - // See if we're loading from a file. (Because about:memory is a non-standard
|
|
510 | - // URL, location.search is undefined, so we have to use location.href
|
|
511 | - // instead.)
|
|
512 | - let search = location.href.split("?")[1];
|
|
513 | - if (search) {
|
|
514 | - let searchSplit = search.split("&");
|
|
515 | - for (let s of searchSplit) {
|
|
516 | - if (s.toLowerCase().startsWith("file=")) {
|
|
517 | - let filename = s.substring("file=".length);
|
|
518 | - updateAboutMemoryFromFile(decodeURIComponent(filename));
|
|
519 | - return;
|
|
520 | - }
|
|
521 | - }
|
|
509 | + // See if we're loading from a file.
|
|
510 | + let { searchParams } = URL.fromURI(document.documentURIObject);
|
|
511 | + let fileParam = searchParams.get("file");
|
|
512 | + if (fileParam) {
|
|
513 | + updateAboutMemoryFromFile(fileParam);
|
|
522 | 514 | }
|
523 | 515 | };
|
524 | 516 |