Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/antitracking/./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp
Warning:line 69, 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-01-224014-2642839-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 "mozilla/dom/StripOnShareRuleBinding.h"
21
22namespace {
23
24mozilla::StaticRefPtr<mozilla::URLQueryStringStripper> gQueryStringStripper;
25
26static const char kQueryStrippingEnabledPref[] =
27 "privacy.query_stripping.enabled";
28static const char kQueryStrippingEnabledPBMPref[] =
29 "privacy.query_stripping.enabled.pbmode";
30static const char kQueryStrippingOnShareEnabledPref[] =
31 "privacy.query_stripping.strip_on_share.enabled";
32
33} // namespace
34
35namespace mozilla {
36
37NS_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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 38
); __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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 38); __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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 38)
; __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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 38); __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"
, 38); 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; }
38 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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 38
); __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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 38); __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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 38)
; __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"
, 38); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"URLQueryStringStripper\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 38); __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"
, 38); 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; }
39
40// static
41already_AddRefed<URLQueryStringStripper>
42URLQueryStringStripper::GetSingleton() {
43 if (!gQueryStringStripper) {
44 gQueryStringStripper = new URLQueryStringStripper();
45 // Check initial pref state and enable service. We can pass nullptr, because
46 // OnPrefChange doesn't rely on the args.
47 URLQueryStringStripper::OnPrefChange(nullptr, nullptr);
48
49 RunOnShutdown(
50 [&] {
51 DebugOnly<nsresult> rv = gQueryStringStripper->Shutdown();
52 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"
, 53); } } while (false)
53 "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"
, 53); } } while (false)
;
54 gQueryStringStripper = nullptr;
55 },
56 ShutdownPhase::XPCOMShutdown);
57 }
58
59 return do_AddRef(gQueryStringStripper);
60}
61
62URLQueryStringStripper::URLQueryStringStripper() {
63 mIsInitialized = false;
64
65 nsresult rv = Preferences::RegisterCallback(
66 &URLQueryStringStripper::OnPrefChange, kQueryStrippingEnabledPBMPref);
67 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"
, 67); return; } } while (false)
;
68
69 rv = Preferences::RegisterCallback(&URLQueryStringStripper::OnPrefChange,
Value stored to 'rv' is never read
70 kQueryStrippingEnabledPref);
71
72 rv = Preferences::RegisterCallback(&URLQueryStringStripper::OnPrefChange,
73 kQueryStrippingOnShareEnabledPref);
74 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"
, 74); return; } } while (false)
;
75}
76
77NS_IMETHODIMPnsresult
78URLQueryStringStripper::StripForCopyOrShare(nsIURI* aURI,
79 nsIURI** strippedURI) {
80 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"
, 80); return NS_ERROR_INVALID_POINTER; } } while (false)
;
81 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"
, 81); return NS_ERROR_INVALID_POINTER; } } while (false)
;
82 int aStripCount = 0;
83
84 nsresult rv = StripForCopyOrShareInternal(aURI, strippedURI, aStripCount,
85 /* aDry = */ false,
86 /* aStripNestedURIs = */ false);
87 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"
, 87); return rv; } } while (false)
;
88
89 glean::contentblocking::strip_on_share_params_removed.AccumulateSingleSample(
90 aStripCount);
91
92 if (!aStripCount) {
93 return NS_OK;
94 }
95
96 // To calculate difference in length of the URL
97 // after stripping occurs for Telemetry
98 nsAutoCString specOriginalURI;
99 nsAutoCString specStrippedURI;
100
101 rv = aURI->GetDisplaySpec(specOriginalURI);
102 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"
, 102); return rv; } } while (false)
;
103
104 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"
, 104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*strippedURI"
")"); do { MOZ_CrashSequence(__null, 104); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
105
106 rv = (*strippedURI)->GetDisplaySpec(specStrippedURI);
107 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"
, 107); return rv; } } while (false)
;
108
109 uint32_t lengthDiff = specOriginalURI.Length() - specStrippedURI.Length();
110 glean::contentblocking::strip_on_share_length_decrease.AccumulateSingleSample(
111 lengthDiff);
112
113 return NS_OK;
114}
115
116NS_IMETHODIMPnsresult
117URLQueryStringStripper::CanStripForShare(nsIURI* aURI, bool* aCanStrip) {
118 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"
, 118); return NS_ERROR_INVALID_POINTER; } } while (false)
;
119 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"
, 119); return NS_ERROR_INVALID_POINTER; } } while (false)
;
120
121 *aCanStrip = false;
122 int aStripCount = 0;
123 nsresult rv =
124 StripForCopyOrShareInternal(aURI, nullptr, aStripCount, /* aDry = */ true,
125 /* aStripNestedURIs = */ false);
126 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"
, 126); return rv; } } while (false)
;
127
128 *aCanStrip = aStripCount != 0;
129 return NS_OK;
130}
131
132NS_IMETHODIMPnsresult
133URLQueryStringStripper::Strip(nsIURI* aURI, bool aIsPBM, nsIURI** aOutput,
134 uint32_t* aStripCount) {
135 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"
, 135); return NS_ERROR_INVALID_POINTER; } } while (false)
;
136 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"
, 136); return NS_ERROR_INVALID_POINTER; } } while (false)
;
137 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"
, 137); return NS_ERROR_INVALID_POINTER; } } while (false)
;
138
139 *aStripCount = 0;
140
141 if (aIsPBM) {
142 if (!StaticPrefs::privacy_query_stripping_enabled_pbmode()) {
143 return NS_OK;
144 }
145 } else {
146 if (!StaticPrefs::privacy_query_stripping_enabled()) {
147 return NS_OK;
148 }
149 }
150
151 if (CheckAllowList(aURI)) {
152 return NS_OK;
153 }
154
155 return StripQueryString(aURI, aOutput, aStripCount);
156}
157
158// static
159void URLQueryStringStripper::OnPrefChange(const char* aPref, void* aData) {
160 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"
, 160); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gQueryStringStripper"
")"); do { MOZ_CrashSequence(__null, 160); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
161
162 bool prefEnablesComponent =
163 StaticPrefs::privacy_query_stripping_enabled() ||
164 StaticPrefs::privacy_query_stripping_enabled_pbmode() ||
165 StaticPrefs::privacy_query_stripping_strip_on_share_enabled();
166
167 nsresult rv;
168 if (prefEnablesComponent) {
169 rv = gQueryStringStripper->Init();
170 } else {
171 rv = gQueryStringStripper->Shutdown();
172 }
173 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"
, 173); return; } } while (false)
;
174}
175
176nsresult URLQueryStringStripper::Init() {
177 nsresult rv;
178 if (mIsInitialized) {
179 rv = gQueryStringStripper->ManageObservers();
180 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"
, 180); return rv; } } while (false)
;
181 return NS_OK;
182 }
183 mIsInitialized = true;
184
185 mListService = do_GetService("@mozilla.org/query-stripping-list-service;1");
186 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"
, 186); return NS_ERROR_FAILURE; } } while (false)
;
187 rv = gQueryStringStripper->ManageObservers();
188 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"
, 188); return rv; } } while (false)
;
189 return NS_OK;
190}
191
192// (Un)registers a QPS/Strip-on-share observer according to the QPS prefs states
193// and the strip-on-share pref state. This is called whenever one of the three
194// prefs changes, to ensure that we are not observing one of the lists although
195// the corresponding feature is not turned on.
196nsresult URLQueryStringStripper::ManageObservers() {
197 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"
, 197); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mListService"
")"); do { MOZ_CrashSequence(__null, 197); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
198 nsresult rv;
199 // Register QPS observer.
200 // We are not listening to QPS but the feature is on, register a listener.
201 if (!mObservingQPS) {
202 if (StaticPrefs::privacy_query_stripping_enabled() ||
203 StaticPrefs::privacy_query_stripping_enabled_pbmode()) {
204 rv = mListService->RegisterAndRunObserver(gQueryStringStripper);
205 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"
, 205); return rv; } } while (false)
;
206 mObservingQPS = true;
207 }
208 } else {
209 // Unregister QPS observer.
210 // We are listening to QPS but the feature is off, unregister.
211 if (!StaticPrefs::privacy_query_stripping_enabled() &&
212 !StaticPrefs::privacy_query_stripping_enabled_pbmode()) {
213 // Clean up QPS lists.
214 mList.Clear();
215 mAllowList.Clear();
216 rv = mListService->UnregisterObserver(this);
217 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"
, 217); return rv; } } while (false)
;
218 mObservingQPS = false;
219 }
220 }
221
222 // Register Strip on Share observer.
223 // We are not listening to strip-on-share but the feature is on, register an
224 // Observer.
225 if (!mObservingStripOnShare) {
226 if (StaticPrefs::privacy_query_stripping_strip_on_share_enabled()) {
227 rv = mListService->RegisterAndRunObserverStripOnShare(
228 gQueryStringStripper);
229 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"
, 229); return rv; } } while (false)
;
230 mObservingStripOnShare = true;
231 }
232 } else {
233 // Unregister Strip on Share observer.
234 // We are listening to strip-on-share but the feature is off, unregister.
235 if (!StaticPrefs::privacy_query_stripping_strip_on_share_enabled()) {
236 // Clean up strip-on-share list
237 mStripOnShareGlobal.reset();
238 mStripOnShareHostMap.Clear();
239 mStripOnShareSchemelessSiteMap.Clear();
240 rv = mListService->UnregisterStripOnShareObserver(this);
241 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"
, 241); return rv; } } while (false)
;
242 mObservingStripOnShare = false;
243 }
244 }
245 return NS_OK;
246}
247
248nsresult URLQueryStringStripper::Shutdown() {
249 if (!mIsInitialized) {
250 return NS_OK;
251 }
252 nsresult rv = gQueryStringStripper->ManageObservers();
253 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"
, 253); return rv; } } while (false)
;
254 mIsInitialized = false;
255 mListService = nullptr;
256 return NS_OK;
257}
258
259nsresult URLQueryStringStripper::StripQueryString(nsIURI* aURI,
260 nsIURI** aOutput,
261 uint32_t* aStripCount) {
262 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"
, 262); return NS_ERROR_INVALID_POINTER; } } while (false)
;
263 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"
, 263); return NS_ERROR_INVALID_POINTER; } } while (false)
;
264 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"
, 264); return NS_ERROR_INVALID_POINTER; } } while (false)
;
265
266 *aStripCount = 0;
267
268 nsCOMPtr<nsIURI> uri(aURI);
269
270 nsAutoCString query;
271 nsresult rv = aURI->GetQuery(query);
272 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"
, 272); return rv; } } while (false)
;
273
274 // We don't need to do anything if there is no query string.
275 if (query.IsEmpty()) {
276 return NS_OK;
277 }
278
279 URLParams params;
280
281 URLParams::Parse(query, false, [&](nsCString&& name, nsCString&& value) {
282 nsAutoCString lowerCaseName;
283 ToLowerCase(name, lowerCaseName);
284
285 if (mList.Contains(lowerCaseName)) {
286 *aStripCount += 1;
287
288 // Count how often a specific query param is stripped. For privacy reasons
289 // this will only count query params listed in the Histogram definition.
290 // Calls for any other query params will be discarded.
291 nsAutoCString telemetryLabel("param_");
292 telemetryLabel.Append(lowerCaseName);
293 glean::contentblocking::query_stripping_count_by_param.Get(telemetryLabel)
294 .Add();
295
296 return true;
297 }
298
299 params.Append(name, value);
300 return true;
301 });
302
303 // Return if there is no parameter has been stripped.
304 if (!*aStripCount) {
305 return NS_OK;
306 }
307
308 nsAutoCString newQuery;
309 params.Serialize(newQuery, false);
310
311 (void)NS_MutateURI(uri).SetQuery(newQuery).Finalize(aOutput);
312 return NS_OK;
313}
314
315bool URLQueryStringStripper::CheckAllowList(nsIURI* aURI) {
316 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"
, 316); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ")"); do
{ MOZ_CrashSequence(__null, 316); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
317
318 // Get the site(eTLD+1) from the URI.
319 nsAutoCString baseDomain;
320 nsCOMPtr<nsIEffectiveTLDService> tldService =
321 mozilla::components::EffectiveTLD::Service();
322 nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
323 if (rv == NS_ERROR_HOST_IS_IP_ADDRESS ||
324 rv == NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
325 return false;
326 }
327 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"
, 327); return false; } } while (false)
;
328
329 return mAllowList.Contains(baseDomain);
330}
331
332void URLQueryStringStripper::PopulateStripList(const nsACString& aList) {
333 mList.Clear();
334
335 for (const nsACString& item : aList.Split(' ')) {
336 mList.Insert(item);
337 }
338}
339
340void URLQueryStringStripper::PopulateAllowList(const nsACString& aList) {
341 mAllowList.Clear();
342
343 for (const nsACString& item : aList.Split(',')) {
344 mAllowList.Insert(item);
345 }
346}
347
348NS_IMETHODIMPnsresult
349URLQueryStringStripper::OnQueryStrippingListUpdate(
350 const nsACString& aStripList, const nsACString& aAllowList) {
351 PopulateStripList(aStripList);
352 PopulateAllowList(aAllowList);
353 return NS_OK;
354}
355
356NS_IMETHODIMPnsresult
357URLQueryStringStripper::OnStripOnShareUpdate(const nsTArray<nsString>& aArgs,
358 JSContext* aCx) {
359 mStripOnShareHostMap.Clear();
360 mStripOnShareSchemelessSiteMap.Clear();
361 mStripOnShareGlobal.reset();
362
363 for (const auto& ruleString : aArgs) {
364 dom::StripRule rule;
365 if (NS_WARN_IF(!rule.Init(ruleString))NS_warn_if_impl(!rule.Init(ruleString), "!rule.Init(ruleString)"
, "./../../../../toolkit/components/antitracking/URLQueryStringStripper.cpp"
, 365)
) {
366 // Skipping malformed rules
367 continue;
368 }
369 if (rule.mIsGlobal) {
370 mStripOnShareGlobal = Some(rule);
371 } else {
372 for (const auto& host : rule.mHosts) {
373 mStripOnShareHostMap.InsertOrUpdate(host, rule);
374 }
375 for (const auto& schemelessSite : rule.mSchemelessSites) {
376 mStripOnShareSchemelessSiteMap.InsertOrUpdate(schemelessSite, rule);
377 }
378 }
379 }
380
381 return NS_OK;
382}
383// static
384NS_IMETHODIMPnsresult
385URLQueryStringStripper::TestGetStripList(nsACString& aStripList) {
386 aStripList.Truncate();
387
388 StringJoinAppend(
389 aStripList, " "_ns, mList,
390 [](auto& aResult, const auto& aValue) { aResult.Append(aValue); });
391 return NS_OK;
392}
393
394/* nsIObserver */
395NS_IMETHODIMPnsresult
396URLQueryStringStripper::Observe(nsISupports*, const char* aTopic,
397 const char16_t*) {
398 // Since this class is created at profile-after-change by the Category
399 // Manager, it's expected to implement nsIObserver; however, we have nothing
400 // interesting to do here.
401 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"
, 401); AnnotateMozCrashReason("MOZ_ASSERT" "(" "strcmp(aTopic, \"profile-after-change\") == 0"
")"); do { MOZ_CrashSequence(__null, 401); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
402
403 return NS_OK;
404}
405
406bool URLQueryStringStripper::ShouldStripParam(const nsACString& aHost,
407 const nsACString& aSchemelessSite,
408 const nsACString& aName) {
409 nsAutoCString lowerCaseName;
410 ToLowerCase(aName, lowerCaseName);
411 const auto matches = [&lowerCaseName](const dom::StripRule& aRule) {
412 return aRule.mQueryParams.Contains(lowerCaseName);
413 };
414 // Look through the global rules.
415 if (mStripOnShareGlobal.isSome() && matches(mStripOnShareGlobal.ref())) {
416 return true;
417 }
418 // Check for site specific rules.
419 if (auto entry = mStripOnShareHostMap.Lookup(aHost);
420 entry && matches(entry.Data())) {
421 return true;
422 }
423 if (auto entry = mStripOnShareSchemelessSiteMap.Lookup(aSchemelessSite);
424 entry && matches(entry.Data())) {
425 return true;
426 }
427 // no rule covering
428 return false;
429}
430
431int URLQueryStringStripper::TryStripValue(const nsACString& aHost,
432 nsACString& aValue, bool aDry) {
433 nsresult rv;
434
435 nsAutoCString decodeValue;
436 URLParams::DecodeString(aValue, decodeValue);
437
438 nsCOMPtr<nsIURI> nestedURI;
439 rv = NS_NewURI(getter_AddRefs(nestedURI), decodeValue);
440
441 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
442 return 0;
443 }
444
445 int stripCount = 0;
446 // recurse down
447 nsCOMPtr<nsIURI> strippedNestedURI;
448 rv = StripForCopyOrShareInternal(nestedURI, getter_AddRefs(strippedNestedURI),
449 stripCount, aDry,
450 /* aStripNestedURIs = */ true);
451
452 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && stripCount != 0) {
453 if (aDry) {
454 return 1;
455 }
456 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"
, 457); AnnotateMozCrashReason("MOZ_ASSERT" "(" "strippedNestedURI"
") (" "URL must be returned if stripCount != 0 in non-dry mode"
")"); do { MOZ_CrashSequence(__null, 457); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
457 "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"
, 457); AnnotateMozCrashReason("MOZ_ASSERT" "(" "strippedNestedURI"
") (" "URL must be returned if stripCount != 0 in non-dry mode"
")"); do { MOZ_CrashSequence(__null, 457); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
458 nsAutoCString nestedURIString;
459 rv = strippedNestedURI->GetSpec(nestedURIString);
460 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"
, 460)
) {
461 return 0;
462 }
463
464 // Overwrite aValue with URL with stripped query parameters
465 aValue.Truncate();
466 URLParams::SerializeString(nestedURIString, aValue);
467 return stripCount;
468 }
469 return 0;
470}
471
472nsresult URLQueryStringStripper::StripForCopyOrShareInternal(
473 nsIURI* aURI, nsIURI** aStrippedURI, int& aStripCount, bool aDry,
474 bool aStripNestedURIs) {
475 if (!StaticPrefs::privacy_query_stripping_strip_on_share_enabled()) {
476 aStripCount = 0;
477 return NS_OK;
478 }
479
480 nsAutoCString query;
481 nsresult rv = aURI->GetQuery(query);
482 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"
, 482); return rv; } } while (false)
;
483
484 // We don't need to do anything if there is no query string.
485 if (query.IsEmpty()) {
486 return NS_OK;
487 }
488
489 nsAutoCString host;
490 rv = aURI->GetHost(host);
491 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"
, 491); return rv; } } while (false)
;
492
493 const nsCOMPtr<nsIEffectiveTLDService> eTLDService =
494 mozilla::components::EffectiveTLD::Service(&rv);
495 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"
, 495); return rv; } } while (false)
;
496
497 nsAutoCString schemelessSite;
498 rv = eTLDService->GetSchemelessSite(aURI, schemelessSite);
499 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"
, 499); return rv; } } while (false)
;
500
501 URLParams params;
502
503 URLParams::Parse(query, false, [&](nsCString&& aName, nsCString&& aValue) {
504 if (ShouldStripParam(host, schemelessSite, aName)) {
505 aStripCount++;
506 // If we found a query param to strip in dry mode, skip iterating over the
507 // remaining ones (we return greedily). Otherwise don't add the param to
508 // the new list and continue with the next one.
509 return !aDry;
510 }
511
512 // Only if it is top layer of the recursion then it checks if the value of
513 // the query parameter is a valid URI if not then it gets added back to the
514 // query, if it is then it gets passed back into this method but with the
515 // recursive stripping flag set to true
516 if (!aStripNestedURIs) {
517 aStripCount += TryStripValue(host, aValue, aDry);
518 }
519 if (aDry) {
520 return aStripCount == 0;
521 }
522
523 params.Append(aName, aValue);
524 return true;
525 });
526
527 // Returns null for aStrippedURI if no query params have been stripped
528 // or in dry mode.
529 if (!aStripCount || aDry || !aStrippedURI) {
530 return NS_OK;
531 }
532
533 nsAutoCString newQuery;
534 params.Serialize(newQuery, false);
535 return NS_MutateURI(aURI).SetQuery(newQuery).Finalize(aStrippedURI);
536}
537} // namespace mozilla