Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/antitracking/./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp
Warning:line 109, column 3
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_antitracking1.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/antitracking -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/antitracking -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/toolkit/components/antitracking -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/antitracking -I /root/firefox-clang/netwerk/base -I /root/firefox-clang/netwerk/protocol/http -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-23-100101-1972947-1 -x c++ Unified_cpp_antitracking1.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#include "URLQueryStringStripper.h"
6
7#include "mozilla/Components.h"
8#include "mozilla/ClearOnShutdown.h"
9#include "mozilla/StaticPrefs_privacy.h"
10#include "mozilla/StaticPtr.h"
11#include "mozilla/glean/AntitrackingMetrics.h"
12
13#include "nsIEffectiveTLDService.h"
14#include "nsISupportsImpl.h"
15#include "nsIURI.h"
16#include "nsIURIMutator.h"
17#include "nsUnicharUtils.h"
18#include "nsURLHelper.h"
19#include "nsNetUtil.h"
20#include "nsCharSeparatedTokenizer.h"
21#include "mozilla/dom/StripOnShareRuleBinding.h"
22
23namespace {
24
25mozilla::StaticRefPtr<mozilla::URLQueryStringStripper> gQueryStringStripper;
26
27static const char kQueryStrippingEnabledPref[] =
28 "privacy.query_stripping.enabled";
29static const char kQueryStrippingEnabledPBMPref[] =
30 "privacy.query_stripping.enabled.pbmode";
31static const char kQueryStrippingOnShareEnabledPref[] =
32 "privacy.query_stripping.strip_on_share.enabled";
33
34struct QueryParam {
35 nsCString mName;
36 nsCString mValue;
37 bool mHasEquals = false;
38};
39
40// Splits a raw (still percent-encoded) query string into QueryParam segments,
41// preserving the '='-vs-no-'=' distinction.
42void SplitQueryPreservingEquals(const nsACString& aQuery,
43 nsTArray<QueryParam>& aOutParams) {
44 mozilla::URLParams::ParseWithEquals(
45 aQuery, /* aShouldDecode = */ false,
46 [&](nsCString&& aName, nsCString&& aValue, bool aHasEquals) {
47 QueryParam* param = aOutParams.AppendElement();
48 param->mName = std::move(aName);
49 param->mValue = std::move(aValue);
50 param->mHasEquals = aHasEquals;
51 return true;
52 });
53}
54
55// Rejoins params into a query string, emitting '=' for segments that
56// originally had one.
57void SerializeQueryPreservingEquals(const nsTArray<QueryParam>& aParams,
58 nsACString& aOutQuery) {
59 aOutQuery.Truncate();
60 bool first = true;
61 for (const QueryParam& param : aParams) {
62 if (!first) {
63 aOutQuery.Append('&');
64 }
65 first = false;
66 aOutQuery.Append(param.mName);
67 if (param.mHasEquals) {
68 aOutQuery.Append('=');
69 aOutQuery.Append(param.mValue);
70 }
71 }
72}
73} // namespace
74
75namespace mozilla {
76
77NS_IMPL_ISUPPORTS(URLQueryStringStripper, nsIObserver,MozExternalRefCountType URLQueryStringStripper::AddRef(void) {
static_assert(!std::is_destructible_v<URLQueryStringStripper
>, "Reference-counted class " "URLQueryStringStripper" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 78
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("URLQueryStringStripper" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("URLQueryStringStripper" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"URLQueryStringStripper\" != nullptr"
" (" "Must specify a name" ")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 78); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("URLQueryStringStripper" " not thread-safe"); nsrefcnt count
= ++mRefCnt; NS_LogAddRef((this), (count), ("URLQueryStringStripper"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
URLQueryStringStripper::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 78)
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("URLQueryStringStripper" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("URLQueryStringStripper" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"URLQueryStringStripper\" != nullptr"
" (" "Must specify a name" ")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 78); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("URLQueryStringStripper" " not thread-safe"); const char* const
nametmp = "URLQueryStringStripper"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
URLQueryStringStripper::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(3 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<URLQueryStringStripper, nsIObserver>,
int32_t( reinterpret_cast<char*>(static_cast<nsIObserver
*>((URLQueryStringStripper*)0x1000)) - reinterpret_cast<
char*>((URLQueryStringStripper*)0x1000))}, {&mozilla::
detail::kImplementedIID<URLQueryStringStripper, nsIURLQueryStringStripper
>, int32_t( reinterpret_cast<char*>(static_cast<nsIURLQueryStringStripper
*>((URLQueryStringStripper*)0x1000)) - reinterpret_cast<
char*>((URLQueryStringStripper*)0x1000))}, {&mozilla::
detail::kImplementedIID<URLQueryStringStripper, nsIURLQueryStrippingListObserver
>, int32_t( reinterpret_cast<char*>(static_cast<nsIURLQueryStrippingListObserver
*>((URLQueryStringStripper*)0x1000)) - reinterpret_cast<
char*>((URLQueryStringStripper*)0x1000))}, {&mozilla::
detail::kImplementedIID<URLQueryStringStripper, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIObserver*>((URLQueryStringStripper
*)0x1000))) - reinterpret_cast<char*>((URLQueryStringStripper
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
78 nsIURLQueryStringStripper, nsIURLQueryStrippingListObserver)MozExternalRefCountType URLQueryStringStripper::AddRef(void) {
static_assert(!std::is_destructible_v<URLQueryStringStripper
>, "Reference-counted class " "URLQueryStringStripper" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 78
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("URLQueryStringStripper" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("URLQueryStringStripper" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"URLQueryStringStripper\" != nullptr"
" (" "Must specify a name" ")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 78); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("URLQueryStringStripper" " not thread-safe"); nsrefcnt count
= ++mRefCnt; NS_LogAddRef((this), (count), ("URLQueryStringStripper"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
URLQueryStringStripper::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 78)
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("URLQueryStringStripper" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("URLQueryStringStripper" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"URLQueryStringStripper\" != nullptr"
" (" "Must specify a name" ")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 78); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); if (!mRefCnt.isThreadSafe) _mOwningThread.AssertOwnership
("URLQueryStringStripper" " not thread-safe"); const char* const
nametmp = "URLQueryStringStripper"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
URLQueryStringStripper::QueryInterface(const nsIID& aIID
, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 78); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(3 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<URLQueryStringStripper, nsIObserver>,
int32_t( reinterpret_cast<char*>(static_cast<nsIObserver
*>((URLQueryStringStripper*)0x1000)) - reinterpret_cast<
char*>((URLQueryStringStripper*)0x1000))}, {&mozilla::
detail::kImplementedIID<URLQueryStringStripper, nsIURLQueryStringStripper
>, int32_t( reinterpret_cast<char*>(static_cast<nsIURLQueryStringStripper
*>((URLQueryStringStripper*)0x1000)) - reinterpret_cast<
char*>((URLQueryStringStripper*)0x1000))}, {&mozilla::
detail::kImplementedIID<URLQueryStringStripper, nsIURLQueryStrippingListObserver
>, int32_t( reinterpret_cast<char*>(static_cast<nsIURLQueryStrippingListObserver
*>((URLQueryStringStripper*)0x1000)) - reinterpret_cast<
char*>((URLQueryStringStripper*)0x1000))}, {&mozilla::
detail::kImplementedIID<URLQueryStringStripper, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIObserver*>((URLQueryStringStripper
*)0x1000))) - reinterpret_cast<char*>((URLQueryStringStripper
*)0x1000))}, { nullptr, 0 } } ; static_assert(std::size(table
) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
79
80// static
81already_AddRefed<URLQueryStringStripper>
82URLQueryStringStripper::GetSingleton() {
83 if (!gQueryStringStripper) {
84 gQueryStringStripper = new URLQueryStringStripper();
85 // Check initial pref state and enable service. We can pass nullptr, because
86 // OnPrefChange doesn't rely on the args.
87 URLQueryStringStripper::OnPrefChange(nullptr, nullptr);
88
89 RunOnShutdown(
90 [&] {
91 DebugOnly<nsresult> rv = gQueryStringStripper->Shutdown();
92 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "URLQueryStringStripper::Shutdown failed"
, "NS_SUCCEEDED(rv)", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 93); } } while (false)
93 "URLQueryStringStripper::Shutdown failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "URLQueryStringStripper::Shutdown failed"
, "NS_SUCCEEDED(rv)", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 93); } } while (false)
;
94 gQueryStringStripper = nullptr;
95 },
96 ShutdownPhase::XPCOMShutdown);
97 }
98
99 return do_AddRef(gQueryStringStripper);
100}
101
102URLQueryStringStripper::URLQueryStringStripper() {
103 mIsInitialized = false;
104
105 nsresult rv = Preferences::RegisterCallback(
106 &URLQueryStringStripper::OnPrefChange, kQueryStrippingEnabledPBMPref);
107 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 107); return; } } while (false)
;
108
109 rv = Preferences::RegisterCallback(&URLQueryStringStripper::OnPrefChange,
Value stored to 'rv' is never read
110 kQueryStrippingEnabledPref);
111
112 rv = Preferences::RegisterCallback(&URLQueryStringStripper::OnPrefChange,
113 kQueryStrippingOnShareEnabledPref);
114 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 114); return; } } while (false)
;
115}
116
117NS_IMETHODIMPnsresult
118URLQueryStringStripper::StripForCopyOrShare(nsIURI* aURI,
119 nsIURI** strippedURI) {
120 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 120); return NS_ERROR_INVALID_POINTER; } } while (false)
;
121 NS_ENSURE_ARG_POINTER(strippedURI)do { if ((__builtin_expect(!!(!(strippedURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "strippedURI" ") failed"
, nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 121); return NS_ERROR_INVALID_POINTER; } } while (false)
;
122 int aStripCount = 0;
123
124 nsresult rv = StripForCopyOrShareInternal(aURI, strippedURI, aStripCount,
125 /* aDry = */ false,
126 /* aStripNestedURIs = */ false);
127 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 127); return rv; } } while (false)
;
128
129 glean::contentblocking::strip_on_share_params_removed.AccumulateSingleSample(
130 aStripCount);
131
132 if (!aStripCount) {
133 return NS_OK;
134 }
135
136 // To calculate difference in length of the URL
137 // after stripping occurs for Telemetry
138 nsAutoCString specOriginalURI;
139 nsAutoCString specStrippedURI;
140
141 rv = aURI->GetDisplaySpec(specOriginalURI);
142 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 142); return rv; } } while (false)
;
143
144 MOZ_ASSERT(*strippedURI)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(*strippedURI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*strippedURI))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("*strippedURI", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 144); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*strippedURI"
")"); do { MOZ_CrashSequence(__null, 144); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
145
146 rv = (*strippedURI)->GetDisplaySpec(specStrippedURI);
147 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 147); return rv; } } while (false)
;
148
149 uint32_t lengthDiff = specOriginalURI.Length() - specStrippedURI.Length();
150 glean::contentblocking::strip_on_share_length_decrease.AccumulateSingleSample(
151 lengthDiff);
152
153 return NS_OK;
154}
155
156NS_IMETHODIMPnsresult
157URLQueryStringStripper::CanStripForShare(nsIURI* aURI, bool* aCanStrip) {
158 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 158); return NS_ERROR_INVALID_POINTER; } } while (false)
;
159 NS_ENSURE_ARG_POINTER(aCanStrip)do { if ((__builtin_expect(!!(!(aCanStrip)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCanStrip" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 159); return NS_ERROR_INVALID_POINTER; } } while (false)
;
160
161 *aCanStrip = false;
162 int aStripCount = 0;
163 nsresult rv =
164 StripForCopyOrShareInternal(aURI, nullptr, aStripCount, /* aDry = */ true,
165 /* aStripNestedURIs = */ false);
166 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 166); return rv; } } while (false)
;
167
168 *aCanStrip = aStripCount != 0;
169 return NS_OK;
170}
171
172NS_IMETHODIMPnsresult
173URLQueryStringStripper::Strip(nsIURI* aURI, bool aIsPBM, nsIURI** aOutput,
174 uint32_t* aStripCount) {
175 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 175); return NS_ERROR_INVALID_POINTER; } } while (false)
;
176 NS_ENSURE_ARG_POINTER(aOutput)do { if ((__builtin_expect(!!(!(aOutput)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOutput" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 176); return NS_ERROR_INVALID_POINTER; } } while (false)
;
177 NS_ENSURE_ARG_POINTER(aStripCount)do { if ((__builtin_expect(!!(!(aStripCount)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStripCount" ") failed"
, nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 177); return NS_ERROR_INVALID_POINTER; } } while (false)
;
178
179 *aStripCount = 0;
180
181 if (aIsPBM) {
182 if (!StaticPrefs::privacy_query_stripping_enabled_pbmode()) {
183 return NS_OK;
184 }
185 } else {
186 if (!StaticPrefs::privacy_query_stripping_enabled()) {
187 return NS_OK;
188 }
189 }
190
191 if (CheckAllowList(aURI)) {
192 return NS_OK;
193 }
194
195 return StripQueryString(aURI, aOutput, aStripCount);
196}
197
198// static
199void URLQueryStringStripper::OnPrefChange(const char* aPref, void* aData) {
200 MOZ_ASSERT(gQueryStringStripper)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gQueryStringStripper)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(gQueryStringStripper))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("gQueryStringStripper"
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 200); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gQueryStringStripper"
")"); do { MOZ_CrashSequence(__null, 200); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
201
202 bool prefEnablesComponent =
203 StaticPrefs::privacy_query_stripping_enabled() ||
204 StaticPrefs::privacy_query_stripping_enabled_pbmode() ||
205 StaticPrefs::privacy_query_stripping_strip_on_share_enabled();
206
207 nsresult rv;
208 if (prefEnablesComponent) {
209 rv = gQueryStringStripper->Init();
210 } else {
211 rv = gQueryStringStripper->Shutdown();
212 }
213 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 213); return; } } while (false)
;
214}
215
216nsresult URLQueryStringStripper::Init() {
217 nsresult rv;
218 if (mIsInitialized) {
219 rv = gQueryStringStripper->ManageObservers();
220 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 220); return rv; } } while (false)
;
221 return NS_OK;
222 }
223 mIsInitialized = true;
224
225 mListService = do_GetService("@mozilla.org/query-stripping-list-service;1");
226 NS_ENSURE_TRUE(mListService, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mListService)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mListService" ") failed"
, nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 226); return NS_ERROR_FAILURE; } } while (false)
;
227 rv = gQueryStringStripper->ManageObservers();
228 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 228); return rv; } } while (false)
;
229 return NS_OK;
230}
231
232// (Un)registers a QPS/Strip-on-share observer according to the QPS prefs states
233// and the strip-on-share pref state. This is called whenever one of the three
234// prefs changes, to ensure that we are not observing one of the lists although
235// the corresponding feature is not turned on.
236nsresult URLQueryStringStripper::ManageObservers() {
237 MOZ_ASSERT(mListService)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mListService)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mListService))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mListService", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 237); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mListService"
")"); do { MOZ_CrashSequence(__null, 237); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
238 nsresult rv;
239 // Register QPS observer.
240 // We are not listening to QPS but the feature is on, register a listener.
241 if (!mObservingQPS) {
242 if (StaticPrefs::privacy_query_stripping_enabled() ||
243 StaticPrefs::privacy_query_stripping_enabled_pbmode()) {
244 rv = mListService->RegisterAndRunObserver(gQueryStringStripper);
245 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 245); return rv; } } while (false)
;
246 mObservingQPS = true;
247 }
248 } else {
249 // Unregister QPS observer.
250 // We are listening to QPS but the feature is off, unregister.
251 if (!StaticPrefs::privacy_query_stripping_enabled() &&
252 !StaticPrefs::privacy_query_stripping_enabled_pbmode()) {
253 // Clean up QPS lists.
254 mList.Clear();
255 mAllowList.Clear();
256 rv = mListService->UnregisterObserver(this);
257 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 257); return rv; } } while (false)
;
258 mObservingQPS = false;
259 }
260 }
261
262 // Register Strip on Share observer.
263 // We are not listening to strip-on-share but the feature is on, register an
264 // Observer.
265 if (!mObservingStripOnShare) {
266 if (StaticPrefs::privacy_query_stripping_strip_on_share_enabled()) {
267 rv = mListService->RegisterAndRunObserverStripOnShare(
268 gQueryStringStripper);
269 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 269); return rv; } } while (false)
;
270 mObservingStripOnShare = true;
271 }
272 } else {
273 // Unregister Strip on Share observer.
274 // We are listening to strip-on-share but the feature is off, unregister.
275 if (!StaticPrefs::privacy_query_stripping_strip_on_share_enabled()) {
276 // Clean up strip-on-share list
277 mStripOnShareGlobal.reset();
278 mStripOnShareHostMap.Clear();
279 mStripOnShareSchemelessSiteMap.Clear();
280 rv = mListService->UnregisterStripOnShareObserver(this);
281 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 281); return rv; } } while (false)
;
282 mObservingStripOnShare = false;
283 }
284 }
285 return NS_OK;
286}
287
288nsresult URLQueryStringStripper::Shutdown() {
289 if (!mIsInitialized) {
290 return NS_OK;
291 }
292 nsresult rv = gQueryStringStripper->ManageObservers();
293 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 293); return rv; } } while (false)
;
294 mIsInitialized = false;
295 mListService = nullptr;
296 return NS_OK;
297}
298
299nsresult URLQueryStringStripper::StripQueryString(nsIURI* aURI,
300 nsIURI** aOutput,
301 uint32_t* aStripCount) {
302 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 302); return NS_ERROR_INVALID_POINTER; } } while (false)
;
303 NS_ENSURE_ARG_POINTER(aOutput)do { if ((__builtin_expect(!!(!(aOutput)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOutput" ") failed", nullptr
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 303); return NS_ERROR_INVALID_POINTER; } } while (false)
;
304 NS_ENSURE_ARG_POINTER(aStripCount)do { if ((__builtin_expect(!!(!(aStripCount)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStripCount" ") failed"
, nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 304); return NS_ERROR_INVALID_POINTER; } } while (false)
;
305
306 *aStripCount = 0;
307
308 nsCOMPtr<nsIURI> uri(aURI);
309
310 nsAutoCString query;
311 nsresult rv = aURI->GetQuery(query);
312 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 312); return rv; } } while (false)
;
313
314 // We don't need to do anything if there is no query string.
315 if (query.IsEmpty()) {
316 return NS_OK;
317 }
318
319 nsTArray<QueryParam> params;
320 SplitQueryPreservingEquals(query, params);
321
322 params.RemoveElementsBy([&](const QueryParam& aParam) {
323 nsAutoCString lowerCaseName;
324 ToLowerCase(aParam.mName, lowerCaseName);
325 if (!mList.Contains(lowerCaseName)) {
326 return false;
327 }
328
329 *aStripCount += 1;
330
331 // Count how often a specific query param is stripped. For privacy reasons
332 // this will only count query params listed in the Histogram definition.
333 // Calls for any other query params will be discarded.
334 nsAutoCString telemetryLabel("param_");
335 telemetryLabel.Append(lowerCaseName);
336 glean::contentblocking::query_stripping_count_by_param.Get(telemetryLabel)
337 .Add();
338 return true;
339 });
340
341 // Return if there is no parameter has been stripped.
342 if (!*aStripCount) {
343 return NS_OK;
344 }
345
346 nsAutoCString newQuery;
347 SerializeQueryPreservingEquals(params, newQuery);
348 (void)NS_MutateURI(uri).SetQuery(newQuery).Finalize(aOutput);
349 return NS_OK;
350}
351
352bool URLQueryStringStripper::CheckAllowList(nsIURI* aURI) {
353 MOZ_ASSERT(aURI)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aURI)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aURI))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aURI", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 353); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ")"); do
{ MOZ_CrashSequence(__null, 353); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
354
355 // Get the site(eTLD+1) from the URI.
356 nsAutoCString baseDomain;
357 nsCOMPtr<nsIEffectiveTLDService> tldService =
358 mozilla::components::EffectiveTLD::Service();
359 nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
360 if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
361 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
362 return false;
363 }
364 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "false", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 364); return false; } } while (false)
;
365
366 return mAllowList.Contains(baseDomain);
367}
368
369void URLQueryStringStripper::PopulateStripList(const nsACString& aList) {
370 mList.Clear();
371
372 for (const nsACString& item : aList.Split(' ')) {
373 mList.Insert(item);
374 }
375}
376
377void URLQueryStringStripper::PopulateAllowList(const nsACString& aList) {
378 mAllowList.Clear();
379
380 for (const nsACString& item : aList.Split(',')) {
381 mAllowList.Insert(item);
382 }
383}
384
385NS_IMETHODIMPnsresult
386URLQueryStringStripper::OnQueryStrippingListUpdate(
387 const nsACString& aStripList, const nsACString& aAllowList) {
388 PopulateStripList(aStripList);
389 PopulateAllowList(aAllowList);
390 return NS_OK;
391}
392
393NS_IMETHODIMPnsresult
394URLQueryStringStripper::OnStripOnShareUpdate(const nsTArray<nsString>& aArgs,
395 JSContext* aCx) {
396 mStripOnShareHostMap.Clear();
397 mStripOnShareSchemelessSiteMap.Clear();
398 mStripOnShareGlobal.reset();
399
400 for (const auto& ruleString : aArgs) {
401 dom::StripRule rule;
402 if (NS_WARN_IF(!rule.Init(ruleString))NS_warn_if_impl(!rule.Init(ruleString), "!rule.Init(ruleString)"
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 402)
) {
403 // Skipping malformed rules
404 continue;
405 }
406 if (rule.mIsGlobal) {
407 mStripOnShareGlobal = Some(rule);
408 } else {
409 for (const auto& host : rule.mHosts) {
410 mStripOnShareHostMap.InsertOrUpdate(host, rule);
411 }
412 for (const auto& schemelessSite : rule.mSchemelessSites) {
413 mStripOnShareSchemelessSiteMap.InsertOrUpdate(schemelessSite, rule);
414 }
415 }
416 }
417
418 return NS_OK;
419}
420// static
421NS_IMETHODIMPnsresult
422URLQueryStringStripper::TestGetStripList(nsACString& aStripList) {
423 aStripList.Truncate();
424
425 StringJoinAppend(
426 aStripList, " "_ns, mList,
427 [](auto& aResult, const auto& aValue) { aResult.Append(aValue); });
428 return NS_OK;
429}
430
431/* nsIObserver */
432NS_IMETHODIMPnsresult
433URLQueryStringStripper::Observe(nsISupports*, const char* aTopic,
434 const char16_t*) {
435 // Since this class is created at profile-after-change by the Category
436 // Manager, it's expected to implement nsIObserver; however, we have nothing
437 // interesting to do here.
438 MOZ_ASSERT(strcmp(aTopic, "profile-after-change") == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(strcmp(aTopic, "profile-after-change") == 0)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(strcmp(aTopic, "profile-after-change") == 0))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("strcmp(aTopic, \"profile-after-change\") == 0"
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 438); AnnotateMozCrashReason("MOZ_ASSERT" "(" "strcmp(aTopic, \"profile-after-change\") == 0"
")"); do { MOZ_CrashSequence(__null, 438); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
439
440 return NS_OK;
441}
442
443bool URLQueryStringStripper::ShouldStripParam(const nsACString& aHost,
444 const nsACString& aSchemelessSite,
445 const nsACString& aName) {
446 nsAutoCString lowerCaseName;
447 ToLowerCase(aName, lowerCaseName);
448 const auto matches = [&lowerCaseName](const dom::StripRule& aRule) {
449 return aRule.mQueryParams.Contains(lowerCaseName);
450 };
451 // Look through the global rules.
452 if (mStripOnShareGlobal.isSome() && matches(mStripOnShareGlobal.ref())) {
453 return true;
454 }
455 // Check for site specific rules.
456 if (auto entry = mStripOnShareHostMap.Lookup(aHost);
457 entry && matches(entry.Data())) {
458 return true;
459 }
460 if (auto entry = mStripOnShareSchemelessSiteMap.Lookup(aSchemelessSite);
461 entry && matches(entry.Data())) {
462 return true;
463 }
464 // no rule covering
465 return false;
466}
467
468int URLQueryStringStripper::TryStripValue(const nsACString& aHost,
469 nsACString& aValue, bool aDry) {
470 nsresult rv;
471
472 nsAutoCString decodeValue;
473 URLParams::DecodeString(aValue, decodeValue);
474
475 nsCOMPtr<nsIURI> nestedURI;
476 rv = NS_NewURI(getter_AddRefs(nestedURI), decodeValue);
477
478 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
479 return 0;
480 }
481
482 int stripCount = 0;
483 // recurse down
484 nsCOMPtr<nsIURI> strippedNestedURI;
485 rv = StripForCopyOrShareInternal(nestedURI, getter_AddRefs(strippedNestedURI),
486 stripCount, aDry,
487 /* aStripNestedURIs = */ true);
488
489 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && stripCount != 0) {
490 if (aDry) {
491 return 1;
492 }
493 MOZ_ASSERT(strippedNestedURI,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(strippedNestedURI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(strippedNestedURI))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("strippedNestedURI"
" (" "URL must be returned if stripCount != 0 in non-dry mode"
")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 494); AnnotateMozCrashReason("MOZ_ASSERT" "(" "strippedNestedURI"
") (" "URL must be returned if stripCount != 0 in non-dry mode"
")"); do { MOZ_CrashSequence(__null, 494); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
494 "URL must be returned if stripCount != 0 in non-dry mode")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(strippedNestedURI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(strippedNestedURI))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("strippedNestedURI"
" (" "URL must be returned if stripCount != 0 in non-dry mode"
")", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 494); AnnotateMozCrashReason("MOZ_ASSERT" "(" "strippedNestedURI"
") (" "URL must be returned if stripCount != 0 in non-dry mode"
")"); do { MOZ_CrashSequence(__null, 494); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
495 nsAutoCString nestedURIString;
496 rv = strippedNestedURI->GetSpec(nestedURIString);
497 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 497)
) {
498 return 0;
499 }
500
501 // Overwrite aValue with URL with stripped query parameters
502 aValue.Truncate();
503 URLParams::SerializeString(nestedURIString, aValue);
504 return stripCount;
505 }
506 return 0;
507}
508
509nsresult URLQueryStringStripper::StripForCopyOrShareInternal(
510 nsIURI* aURI, nsIURI** aStrippedURI, int& aStripCount, bool aDry,
511 bool aStripNestedURIs) {
512 if (!StaticPrefs::privacy_query_stripping_strip_on_share_enabled()) {
513 aStripCount = 0;
514 return NS_OK;
515 }
516
517 nsAutoCString query;
518 nsresult rv = aURI->GetQuery(query);
519 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 519); return rv; } } while (false)
;
520
521 // We don't need to do anything if there is no query string.
522 if (query.IsEmpty()) {
523 return NS_OK;
524 }
525
526 nsAutoCString host;
527 rv = aURI->GetHost(host);
528 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 528); return rv; } } while (false)
;
529
530 const nsCOMPtr<nsIEffectiveTLDService> eTLDService =
531 mozilla::components::EffectiveTLD::Service(&rv);
532 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 532); return rv; } } while (false)
;
533
534 nsAutoCString schemelessSite;
535 rv = eTLDService->GetSchemelessSite(aURI, schemelessSite);
536 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 536); return rv; } } while (false)
;
537
538 nsTArray<QueryParam> inParams;
539 SplitQueryPreservingEquals(query, inParams);
540
541 nsTArray<QueryParam> outParams;
542 for (QueryParam& param : inParams) {
543 if (ShouldStripParam(host, schemelessSite, param.mName)) {
544 aStripCount++;
545 // If we found a query param to strip in dry mode, skip iterating over
546 // the remaining ones (we return greedily).
547 if (aDry) {
548 break;
549 }
550 continue;
551 }
552
553 // Only if it is top layer of the recursion then it checks if the value of
554 // the query parameter is a valid URI if not then it gets added back to the
555 // query, if it is then it gets passed back into this method but with the
556 // recursive stripping flag set to true
557 if (!aStripNestedURIs) {
558 aStripCount += TryStripValue(host, param.mValue, aDry);
559 }
560
561 if (aDry) {
562 if (aStripCount == 0) {
563 continue;
564 }
565 break;
566 }
567
568 outParams.AppendElement(std::move(param));
569 }
570
571 // Returns null for aStrippedURI if no query params have been stripped
572 // or in dry mode.
573 if (!aStripCount || aDry || !aStrippedURI) {
574 return NS_OK;
575 }
576
577 nsAutoCString newQuery;
578 SerializeQueryPreservingEquals(outParams, newQuery);
579 return NS_MutateURI(aURI).SetQuery(newQuery).Finalize(aStrippedURI);
580}
581} // namespace mozilla