File: | var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp |
Warning: | line 518, column 5 Value stored to 'rv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 |
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | |
5 | #include "chromium/safebrowsing.pb.h" |
6 | #include "nsEscape.h" |
7 | #include "nsString.h" |
8 | #include "nsIURI.h" |
9 | #include "nsIURIMutator.h" |
10 | #include "nsIURL.h" |
11 | #include "nsIXULRuntime.h" |
12 | #include "nsUrlClassifierUtils.h" |
13 | #include "nsTArray.h" |
14 | #include "nsReadableUtils.h" |
15 | #include "plbase64.h" |
16 | #include "nsPrintfCString.h" |
17 | #include "mozilla/ClearOnShutdown.h" |
18 | #include "mozilla/Sprintf.h" |
19 | #include "mozilla/StaticPtr.h" |
20 | #include "mozilla/Mutex.h" |
21 | #include "nsIRedirectHistoryEntry.h" |
22 | #include "nsIHttpChannelInternal.h" |
23 | #include "mozIThirdPartyUtil.h" |
24 | #include "nsIDocShell.h" |
25 | #include "mozilla/TextUtils.h" |
26 | #include "mozilla/Preferences.h" |
27 | #include "mozilla/Services.h" |
28 | #include "mozilla/Telemetry.h" |
29 | #include "nsNetUtil.h" |
30 | #include "nsIHttpChannel.h" |
31 | #include "nsIObserverService.h" |
32 | #include "nsIPrefBranch.h" |
33 | #include "nsIPrefService.h" |
34 | #include "nsPIDOMWindow.h" |
35 | #include "nsServiceManagerUtils.h" |
36 | #include "nsThreadManager.h" |
37 | #include "nsTHashSet.h" |
38 | #include "Classifier.h" |
39 | #include "Entries.h" |
40 | #include "prprf.h" |
41 | #include "prtime.h" |
42 | |
43 | #define DEFAULT_PROTOCOL_VERSION"2.2" "2.2" |
44 | |
45 | using namespace mozilla; |
46 | using namespace mozilla::safebrowsing; |
47 | |
48 | static mozilla::StaticRefPtr<nsUrlClassifierUtils> gUrlClassifierUtils; |
49 | |
50 | static char int_to_hex_digit(int32_t i) { |
51 | NS_ASSERTION((i >= 0) && (i <= 15), "int too big in int_to_hex_digit")do { if (!((i >= 0) && (i <= 15))) { NS_DebugBreak (NS_DEBUG_ASSERTION, "int too big in int_to_hex_digit", "(i >= 0) && (i <= 15)" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 51); MOZ_PretendNoReturn(); } } while (0); |
52 | return static_cast<char>(((i < 10) ? (i + '0') : ((i - 10) + 'A'))); |
53 | } |
54 | |
55 | static bool IsDecimal(const nsACString& num) { |
56 | for (uint32_t i = 0; i < num.Length(); i++) { |
57 | if (!mozilla::IsAsciiDigit(num[i])) { |
58 | return false; |
59 | } |
60 | } |
61 | |
62 | return true; |
63 | } |
64 | |
65 | static bool IsHex(const nsACString& num) { |
66 | if (num.Length() < 3) { |
67 | return false; |
68 | } |
69 | |
70 | if (num[0] != '0' || !(num[1] == 'x' || num[1] == 'X')) { |
71 | return false; |
72 | } |
73 | |
74 | for (uint32_t i = 2; i < num.Length(); i++) { |
75 | if (!mozilla::IsAsciiHexDigit(num[i])) { |
76 | return false; |
77 | } |
78 | } |
79 | |
80 | return true; |
81 | } |
82 | |
83 | static bool IsOctal(const nsACString& num) { |
84 | if (num.Length() < 2) { |
85 | return false; |
86 | } |
87 | |
88 | if (num[0] != '0') { |
89 | return false; |
90 | } |
91 | |
92 | for (uint32_t i = 1; i < num.Length(); i++) { |
93 | if (!mozilla::IsAsciiDigit(num[i]) || num[i] == '8' || num[i] == '9') { |
94 | return false; |
95 | } |
96 | } |
97 | |
98 | return true; |
99 | } |
100 | |
101 | ///////////////////////////////////////////////////////////////// |
102 | // SafeBrowsing V4 related utits. |
103 | |
104 | namespace mozilla { |
105 | namespace safebrowsing { |
106 | |
107 | static PlatformType GetPlatformType() { |
108 | #if defined(ANDROID) |
109 | return ANDROID_PLATFORM; |
110 | #elif defined(XP_MACOSX) |
111 | return OSX_PLATFORM; |
112 | #elif defined(XP_LINUX1) |
113 | return LINUX_PLATFORM; |
114 | #elif defined(XP_WIN) |
115 | return WINDOWS_PLATFORM; |
116 | #else |
117 | // Default to Linux for other platforms (see bug 1362501). |
118 | return LINUX_PLATFORM; |
119 | #endif |
120 | } |
121 | |
122 | typedef FetchThreatListUpdatesRequest_ListUpdateRequest ListUpdateRequest; |
123 | typedef FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints Constraints; |
124 | |
125 | static void InitListUpdateRequest(ThreatType aThreatType, |
126 | const nsCString& aStateBase64, |
127 | ListUpdateRequest* aListUpdateRequest) { |
128 | aListUpdateRequest->set_threat_type(aThreatType); |
129 | PlatformType platform = GetPlatformType(); |
130 | #if defined(ANDROID) |
131 | // Temporary hack to fix bug 1441345. |
132 | if ((aThreatType == SOCIAL_ENGINEERING_PUBLIC) || |
133 | (aThreatType == SOCIAL_ENGINEERING)) { |
134 | platform = LINUX_PLATFORM; |
135 | } |
136 | #endif |
137 | aListUpdateRequest->set_platform_type(platform); |
138 | aListUpdateRequest->set_threat_entry_type(URL); |
139 | |
140 | Constraints* contraints = new Constraints(); |
141 | contraints->add_supported_compressions(RICE); |
142 | aListUpdateRequest->set_allocated_constraints(contraints); |
143 | |
144 | // Only set non-empty state. |
145 | if (!aStateBase64.IsEmpty()) { |
146 | nsCString stateBinary; |
147 | nsresult rv = Base64Decode(aStateBase64, stateBinary); |
148 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) { |
149 | aListUpdateRequest->set_state(stateBinary.get(), stateBinary.Length()); |
150 | } |
151 | } |
152 | } |
153 | |
154 | static ClientInfo* CreateClientInfo() { |
155 | ClientInfo* c = new ClientInfo(); |
156 | |
157 | nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1"); |
158 | |
159 | nsAutoCString clientId; |
160 | nsresult rv = prefBranch->GetCharPref("browser.safebrowsing.id", clientId); |
161 | |
162 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
163 | clientId = "Firefox"; // Use "Firefox" as fallback. |
164 | } |
165 | |
166 | c->set_client_id(clientId.get()); |
167 | |
168 | return c; |
169 | } |
170 | |
171 | static bool IsAllowedOnCurrentPlatform(uint32_t aThreatType) { |
172 | PlatformType platform = GetPlatformType(); |
173 | |
174 | switch (aThreatType) { |
175 | case POTENTIALLY_HARMFUL_APPLICATION: |
176 | // Bug 1388582 - Google server would respond 404 error if the request |
177 | // contains PHA on non-mobile platform. |
178 | return ANDROID_PLATFORM == platform; |
179 | case MALICIOUS_BINARY: |
180 | case CSD_DOWNLOAD_WHITELIST: |
181 | // Bug 1392204 - 'goog-downloadwhite-proto' and 'goog-badbinurl-proto' |
182 | // are not available on android. |
183 | return ANDROID_PLATFORM != platform; |
184 | } |
185 | // We allow every threat type not listed in the switch cases. |
186 | return true; |
187 | } |
188 | |
189 | } // end of namespace safebrowsing. |
190 | } // end of namespace mozilla. |
191 | |
192 | // static |
193 | already_AddRefed<nsUrlClassifierUtils> |
194 | nsUrlClassifierUtils::GetXPCOMSingleton() { |
195 | if (gUrlClassifierUtils) { |
196 | return do_AddRef(gUrlClassifierUtils); |
197 | } |
198 | |
199 | RefPtr<nsUrlClassifierUtils> utils = new nsUrlClassifierUtils(); |
200 | if (NS_WARN_IF(NS_FAILED(utils->Init()))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(utils ->Init())), 0))), "NS_FAILED(utils->Init())", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 200)) { |
201 | return nullptr; |
202 | } |
203 | |
204 | // Note: This is cleared in the nsUrlClassifierUtils destructor. |
205 | gUrlClassifierUtils = utils.get(); |
206 | ClearOnShutdown(&gUrlClassifierUtils); |
207 | return utils.forget(); |
208 | } |
209 | |
210 | // static |
211 | nsUrlClassifierUtils* nsUrlClassifierUtils::GetInstance() { |
212 | if (!gUrlClassifierUtils) { |
213 | RefPtr<nsUrlClassifierUtils> utils = GetXPCOMSingleton(); |
214 | } |
215 | |
216 | return gUrlClassifierUtils; |
217 | } |
218 | |
219 | nsUrlClassifierUtils::nsUrlClassifierUtils() |
220 | : mProviderDictLock("nsUrlClassifierUtils.mProviderDictLock") {} |
221 | |
222 | nsUrlClassifierUtils::~nsUrlClassifierUtils() { |
223 | if (gUrlClassifierUtils) { |
224 | MOZ_ASSERT(gUrlClassifierUtils == this)do { static_assert( mozilla::detail::AssertionConditionType< decltype(gUrlClassifierUtils == this)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(gUrlClassifierUtils == this) )), 0))) { do { } while (false); MOZ_ReportAssertionFailure("gUrlClassifierUtils == this" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 224); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gUrlClassifierUtils == this" ")"); do { *((volatile int*)__null) = 224; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
225 | gUrlClassifierUtils = nullptr; |
226 | } |
227 | } |
228 | |
229 | nsresult nsUrlClassifierUtils::Init() { |
230 | // nsIUrlClassifierUtils is a thread-safe service so it's |
231 | // allowed to use on non-main threads. However, building |
232 | // the provider dictionary must be on the main thread. |
233 | // We forcefully load nsUrlClassifierUtils in |
234 | // nsUrlClassifierDBService::Init() to ensure we must |
235 | // now be on the main thread. |
236 | nsresult rv = ReadProvidersFromPrefs(mProviderDict); |
237 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 237); return rv; } } while (false); |
238 | |
239 | // Add an observer for shutdown |
240 | nsCOMPtr<nsIObserverService> observerService = |
241 | mozilla::services::GetObserverService(); |
242 | if (!observerService) return NS_ERROR_FAILURE; |
243 | |
244 | observerService->AddObserver(this, "xpcom-shutdown-threads", false); |
245 | mozilla::Preferences::AddStrongObserver(this, "browser.safebrowsing"); |
246 | |
247 | return NS_OK; |
248 | } |
249 | |
250 | NS_IMPL_ISUPPORTS(nsUrlClassifierUtils, nsIUrlClassifierUtils, nsIObserver)MozExternalRefCountType nsUrlClassifierUtils::AddRef(void) { static_assert (!std::is_destructible_v<nsUrlClassifierUtils>, "Reference-counted class " "nsUrlClassifierUtils" " 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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { *((volatile int*)__null) = 250; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("nsUrlClassifierUtils" != nullptr)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !("nsUrlClassifierUtils" != nullptr))), 0))) { do { } while ( false); MOZ_ReportAssertionFailure("\"nsUrlClassifierUtils\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsUrlClassifierUtils\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 250; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("nsUrlClassifierUtils" " not thread-safe"); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("nsUrlClassifierUtils" ), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType nsUrlClassifierUtils::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" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { *((volatile int*)__null) = 250 ; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("nsUrlClassifierUtils" != nullptr)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !("nsUrlClassifierUtils" != nullptr))), 0))) { do { } while ( false); MOZ_ReportAssertionFailure("\"nsUrlClassifierUtils\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsUrlClassifierUtils\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 250; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("nsUrlClassifierUtils" " not thread-safe"); const char* const nametmp = "nsUrlClassifierUtils"; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (nametmp)); if ( count == 0) { mRefCnt = 1; delete (this); return 0; } return count ; } nsresult nsUrlClassifierUtils::QueryInterface(const nsIID & aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 250); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<nsUrlClassifierUtils, nsIUrlClassifierUtils >, int32_t( reinterpret_cast<char*>(static_cast<nsIUrlClassifierUtils *>((nsUrlClassifierUtils*)0x1000)) - reinterpret_cast<char *>((nsUrlClassifierUtils*)0x1000))}, {&mozilla::detail ::kImplementedIID<nsUrlClassifierUtils, nsIObserver>, int32_t ( reinterpret_cast<char*>(static_cast<nsIObserver*> ((nsUrlClassifierUtils*)0x1000)) - reinterpret_cast<char*> ((nsUrlClassifierUtils*)0x1000))}, {&mozilla::detail::kImplementedIID <nsUrlClassifierUtils, nsISupports>, int32_t(reinterpret_cast <char*>(static_cast<nsISupports*>( static_cast< nsIUrlClassifierUtils*>((nsUrlClassifierUtils*)0x1000))) - reinterpret_cast<char*>((nsUrlClassifierUtils*)0x1000) )}, { nullptr, 0 } } ; static_assert((sizeof(table) / sizeof( table[0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI (static_cast<void*>(this), aIID, aInstancePtr, table); return rv; } |
251 | |
252 | ///////////////////////////////////////////////////////////////////////////// |
253 | // nsIUrlClassifierUtils |
254 | |
255 | NS_IMETHODIMPnsresult |
256 | nsUrlClassifierUtils::GetKeyForURI(nsIURI* uri, nsACString& _retval) { |
257 | nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri); |
258 | if (!innerURI) innerURI = uri; |
259 | |
260 | nsAutoCString host; |
261 | innerURI->GetAsciiHost(host); |
262 | |
263 | if (host.IsEmpty()) { |
264 | return NS_ERROR_MALFORMED_URI; |
265 | } |
266 | |
267 | nsresult rv = CanonicalizeHostname(host, _retval); |
268 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 268); return rv; } } while (false); |
269 | |
270 | nsAutoCString path; |
271 | rv = innerURI->GetPathQueryRef(path); |
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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 272); return rv; } } while (false); |
273 | |
274 | // Strip fragment and query because canonicalization only applies to path |
275 | int32_t ref = path.FindChar('#'); |
276 | if (ref != kNotFound) { |
277 | path.SetLength(ref); |
278 | } |
279 | |
280 | int32_t query = path.FindChar('?'); |
281 | if (query != kNotFound) { |
282 | path.SetLength(query); |
283 | } |
284 | |
285 | nsAutoCString temp; |
286 | rv = CanonicalizePath(path, temp); |
287 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 287); return rv; } } while (false); |
288 | |
289 | _retval.Append(temp); |
290 | |
291 | if (query != kNotFound) { |
292 | nsAutoCString query; |
293 | rv = innerURI->GetQuery(query); |
294 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 294); return rv; } } while (false); |
295 | |
296 | // We have to canonicalize the query too based on |
297 | // https://developers.google.com/safe-browsing/v4/urls-hashing?hl=en#canonicalization |
298 | rv = CanonicalizeQuery(query, temp); |
299 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 299); return rv; } } while (false); |
300 | |
301 | _retval.Append(temp); |
302 | } |
303 | |
304 | return NS_OK; |
305 | } |
306 | |
307 | // We use "goog-*-proto" as the list name for v4, where "proto" indicates |
308 | // it's updated (as well as hash completion) via protobuf. |
309 | // |
310 | // In the mozilla official build, we are allowed to use the |
311 | // private phishing list (goog-phish-proto). See Bug 1288840. |
312 | static const struct { |
313 | const char* mListName; |
314 | uint32_t mThreatType; |
315 | } THREAT_TYPE_CONV_TABLE[] = { |
316 | {"goog-malware-proto", MALWARE_THREAT}, // 1 |
317 | {"googpub-phish-proto", SOCIAL_ENGINEERING_PUBLIC}, // 2 |
318 | {"goog-unwanted-proto", UNWANTED_SOFTWARE}, // 3 |
319 | {"goog-harmful-proto", POTENTIALLY_HARMFUL_APPLICATION}, // 4 |
320 | {"goog-phish-proto", SOCIAL_ENGINEERING}, // 5 |
321 | |
322 | // For application reputation |
323 | {"goog-badbinurl-proto", MALICIOUS_BINARY}, // 7 |
324 | {"goog-downloadwhite-proto", CSD_DOWNLOAD_WHITELIST}, // 9 |
325 | |
326 | // For testing purpose. |
327 | {"moztest-phish-proto", SOCIAL_ENGINEERING_PUBLIC}, // 2 |
328 | {"test-phish-proto", SOCIAL_ENGINEERING_PUBLIC}, // 2 |
329 | {"moztest-unwanted-proto", UNWANTED_SOFTWARE}, // 3 |
330 | {"test-unwanted-proto", UNWANTED_SOFTWARE}, // 3 |
331 | }; |
332 | |
333 | NS_IMETHODIMPnsresult |
334 | nsUrlClassifierUtils::ConvertThreatTypeToListNames(uint32_t aThreatType, |
335 | nsACString& aListNames) { |
336 | for (uint32_t i = 0; i < ArrayLength(THREAT_TYPE_CONV_TABLE); i++) { |
337 | if (aThreatType == THREAT_TYPE_CONV_TABLE[i].mThreatType) { |
338 | if (!aListNames.IsEmpty()) { |
339 | aListNames.AppendLiteral(","); |
340 | } |
341 | aListNames += THREAT_TYPE_CONV_TABLE[i].mListName; |
342 | } |
343 | } |
344 | |
345 | return aListNames.IsEmpty() ? NS_ERROR_FAILURE : NS_OK; |
346 | } |
347 | |
348 | NS_IMETHODIMPnsresult |
349 | nsUrlClassifierUtils::ConvertListNameToThreatType(const nsACString& aListName, |
350 | uint32_t* aThreatType) { |
351 | for (uint32_t i = 0; i < ArrayLength(THREAT_TYPE_CONV_TABLE); i++) { |
352 | if (aListName.EqualsASCII(THREAT_TYPE_CONV_TABLE[i].mListName)) { |
353 | *aThreatType = THREAT_TYPE_CONV_TABLE[i].mThreatType; |
354 | return NS_OK; |
355 | } |
356 | } |
357 | |
358 | return NS_ERROR_FAILURE; |
359 | } |
360 | |
361 | NS_IMETHODIMPnsresult |
362 | nsUrlClassifierUtils::GetProvider(const nsACString& aTableName, |
363 | nsACString& aProvider) { |
364 | MutexAutoLock lock(mProviderDictLock); |
365 | nsCString* provider = nullptr; |
366 | |
367 | if (IsTestTable(aTableName)) { |
368 | aProvider = nsLiteralCString(TESTING_TABLE_PROVIDER_NAME"test"); |
369 | } else if (mProviderDict.Get(aTableName, &provider)) { |
370 | aProvider = provider ? *provider : ""_ns; |
371 | } else { |
372 | aProvider.Truncate(); |
373 | } |
374 | return NS_OK; |
375 | } |
376 | |
377 | NS_IMETHODIMPnsresult |
378 | nsUrlClassifierUtils::GetTelemetryProvider(const nsACString& aTableName, |
379 | nsACString& aProvider) { |
380 | GetProvider(aTableName, aProvider); |
381 | // Exceptionlist known providers to avoid reporting on private ones. |
382 | // An empty provider is treated as "other" |
383 | if (!"mozilla"_ns.Equals(aProvider) && !"google"_ns.Equals(aProvider) && |
384 | !"google4"_ns.Equals(aProvider) && !"baidu"_ns.Equals(aProvider) && |
385 | !"mozcn"_ns.Equals(aProvider) && !"yandex"_ns.Equals(aProvider) && |
386 | !nsLiteralCString(TESTING_TABLE_PROVIDER_NAME"test").Equals(aProvider)) { |
387 | aProvider.AssignLiteral("other"); |
388 | } |
389 | |
390 | return NS_OK; |
391 | } |
392 | |
393 | NS_IMETHODIMPnsresult |
394 | nsUrlClassifierUtils::GetProtocolVersion(const nsACString& aProvider, |
395 | nsACString& aVersion) { |
396 | nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1"); |
397 | if (prefBranch) { |
398 | nsPrintfCString prefName("browser.safebrowsing.provider.%s.pver", |
399 | nsCString(aProvider).get()); |
400 | nsAutoCString version; |
401 | nsresult rv = prefBranch->GetCharPref(prefName.get(), version); |
402 | |
403 | aVersion = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) ? version.get() : DEFAULT_PROTOCOL_VERSION"2.2"; |
404 | } else { |
405 | aVersion = DEFAULT_PROTOCOL_VERSION"2.2"; |
406 | } |
407 | |
408 | return NS_OK; |
409 | } |
410 | |
411 | NS_IMETHODIMPnsresult |
412 | nsUrlClassifierUtils::MakeUpdateRequestV4( |
413 | const nsTArray<nsCString>& aListNames, |
414 | const nsTArray<nsCString>& aStatesBase64, nsACString& aRequest) { |
415 | using namespace mozilla::safebrowsing; |
416 | |
417 | if (aListNames.Length() != aStatesBase64.Length()) { |
418 | return NS_ERROR_INVALID_ARG; |
419 | } |
420 | |
421 | FetchThreatListUpdatesRequest r; |
422 | r.set_allocated_client(CreateClientInfo()); |
423 | |
424 | for (uint32_t i = 0; i < aListNames.Length(); i++) { |
425 | uint32_t threatType; |
426 | nsresult rv = ConvertListNameToThreatType(aListNames[i], &threatType); |
427 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
428 | continue; // Unknown list name. |
429 | } |
430 | if (!IsAllowedOnCurrentPlatform(threatType)) { |
431 | NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 435) |
432 | nsPrintfCString(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 435) |
433 | "Threat type %d (%s) is unsupported on current platform: %d",NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 435) |
434 | threatType, aListNames[i].get(), GetPlatformType())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 435) |
435 | .get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 435); |
436 | continue; // Some threat types are not available on some platforms. |
437 | } |
438 | auto lur = r.mutable_list_update_requests()->Add(); |
439 | InitListUpdateRequest(static_cast<ThreatType>(threatType), aStatesBase64[i], |
440 | lur); |
441 | } |
442 | |
443 | // Then serialize. |
444 | std::string s; |
445 | r.SerializeToString(&s); |
446 | |
447 | nsCString out; |
448 | nsresult rv = Base64URLEncode(s.size(), (const uint8_t*)s.c_str(), |
449 | Base64URLEncodePaddingPolicy::Include, out); |
450 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 450); return rv; } } while (false); |
451 | |
452 | aRequest = out; |
453 | |
454 | return NS_OK; |
455 | } |
456 | |
457 | NS_IMETHODIMPnsresult |
458 | nsUrlClassifierUtils::MakeFindFullHashRequestV4( |
459 | const nsTArray<nsCString>& aListNames, |
460 | const nsTArray<nsCString>& aListStatesBase64, |
461 | const nsTArray<nsCString>& aPrefixesBase64, nsACString& aRequest) { |
462 | if (aListNames.Length() != aListStatesBase64.Length()) { |
463 | return NS_ERROR_INVALID_ARG; |
464 | } |
465 | |
466 | FindFullHashesRequest r; |
467 | r.set_allocated_client(CreateClientInfo()); |
468 | |
469 | nsresult rv; |
470 | |
471 | //------------------------------------------------------------------- |
472 | // Set up FindFullHashesRequest.threat_info. |
473 | auto threatInfo = r.mutable_threat_info(); |
474 | |
475 | PlatformType platform = GetPlatformType(); |
476 | |
477 | // 1) Set threat types. |
478 | for (uint32_t i = 0; i < aListNames.Length(); i++) { |
479 | // Add threat types. |
480 | uint32_t threatType; |
481 | rv = ConvertListNameToThreatType(aListNames[i], &threatType); |
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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 482); return rv; } } while (false); |
483 | if (!IsAllowedOnCurrentPlatform(threatType)) { |
484 | NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 488) |
485 | nsPrintfCString(NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 488) |
486 | "Threat type %d (%s) is unsupported on current platform: %d",NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 488) |
487 | threatType, aListNames[i].get(), GetPlatformType())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 488) |
488 | .get())NS_DebugBreak(NS_DEBUG_WARNING, nsPrintfCString( "Threat type %d (%s) is unsupported on current platform: %d" , threatType, aListNames[i].get(), GetPlatformType()) .get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 488); |
489 | continue; |
490 | } |
491 | threatInfo->add_threat_types((ThreatType)threatType); |
492 | |
493 | #if defined(ANDROID) |
494 | // Temporary hack to fix bug 1441345. |
495 | if (((ThreatType)threatType == SOCIAL_ENGINEERING_PUBLIC) || |
496 | ((ThreatType)threatType == SOCIAL_ENGINEERING)) { |
497 | platform = LINUX_PLATFORM; |
498 | } |
499 | #endif |
500 | |
501 | // Add client states for index 'i' only when the threat type is available |
502 | // on current platform. |
503 | nsCString stateBinary; |
504 | rv = Base64Decode(aListStatesBase64[i], stateBinary); |
505 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 505); return rv; } } while (false); |
506 | r.add_client_states(stateBinary.get(), stateBinary.Length()); |
507 | } |
508 | |
509 | // 2) Set platform type. |
510 | threatInfo->add_platform_types(platform); |
511 | |
512 | // 3) Set threat entry type. |
513 | threatInfo->add_threat_entry_types(URL); |
514 | |
515 | // 4) Set threat entries. |
516 | for (const nsCString& prefix : aPrefixesBase64) { |
517 | nsCString prefixBinary; |
518 | rv = Base64Decode(prefix, prefixBinary); |
Value stored to 'rv' is never read | |
519 | threatInfo->add_threat_entries()->set_hash(prefixBinary.get(), |
520 | prefixBinary.Length()); |
521 | } |
522 | //------------------------------------------------------------------- |
523 | |
524 | // Then serialize. |
525 | std::string s; |
526 | r.SerializeToString(&s); |
527 | |
528 | nsCString out; |
529 | rv = Base64URLEncode(s.size(), (const uint8_t*)s.c_str(), |
530 | Base64URLEncodePaddingPolicy::Include, out); |
531 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 531); return rv; } } while (false); |
532 | |
533 | aRequest = out; |
534 | |
535 | return NS_OK; |
536 | } |
537 | |
538 | // Remove ref, query, userpass, anypart which may contain sensitive data |
539 | static nsresult GetSpecWithoutSensitiveData(nsIURI* aUri, nsACString& aSpec) { |
540 | if (NS_WARN_IF(!aUri)NS_warn_if_impl(!aUri, "!aUri", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 540)) { |
541 | return NS_ERROR_INVALID_ARG; |
542 | } |
543 | |
544 | nsresult rv; |
545 | nsCOMPtr<nsIURL> url(do_QueryInterface(aUri)); |
546 | if (url) { |
547 | nsCOMPtr<nsIURI> clone; |
548 | rv = NS_MutateURI(url) |
549 | .SetQuery(""_ns) |
550 | .SetRef(""_ns) |
551 | .SetUserPass(""_ns) |
552 | .Finalize(clone); |
553 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 553); return rv; } } while (false); |
554 | rv = clone->GetAsciiSpec(aSpec); |
555 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 555); return rv; } } while (false); |
556 | } |
557 | return NS_OK; |
558 | } |
559 | |
560 | static nsresult AddThreatSourceFromChannel(ThreatHit& aHit, |
561 | nsIChannel* aChannel, |
562 | ThreatHit_ThreatSourceType aType) { |
563 | if (NS_WARN_IF(!aChannel)NS_warn_if_impl(!aChannel, "!aChannel", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 563)) { |
564 | return NS_ERROR_INVALID_ARG; |
565 | } |
566 | |
567 | nsresult rv; |
568 | |
569 | auto matchingSource = aHit.add_resources(); |
570 | matchingSource->set_type(aType); |
571 | |
572 | nsCOMPtr<nsIURI> uri; |
573 | rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); |
574 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 574); return rv; } } while (false); |
575 | |
576 | nsCString spec; |
577 | rv = GetSpecWithoutSensitiveData(uri, spec); |
578 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 578); return rv; } } while (false); |
579 | matchingSource->set_url(spec.get()); |
580 | |
581 | nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel); |
582 | if (httpChannel) { |
583 | nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo(); |
584 | if (referrerInfo) { |
585 | nsAutoCString referrerSpec; |
586 | nsCOMPtr<nsIURI> referrer = referrerInfo->GetComputedReferrer(); |
587 | if (referrer) { |
588 | rv = GetSpecWithoutSensitiveData(referrer, referrerSpec); |
589 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 589); return rv; } } while (false); |
590 | matchingSource->set_referrer(referrerSpec.get()); |
591 | } |
592 | } |
593 | } |
594 | |
595 | nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = |
596 | do_QueryInterface(aChannel); |
597 | if (httpChannelInternal) { |
598 | nsCString remoteIp; |
599 | rv = httpChannelInternal->GetRemoteAddress(remoteIp); |
600 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !remoteIp.IsEmpty()) { |
601 | matchingSource->set_remote_ip(remoteIp.get()); |
602 | } |
603 | } |
604 | return NS_OK; |
605 | } |
606 | static nsresult AddThreatSourceFromRedirectEntry( |
607 | ThreatHit& aHit, nsIRedirectHistoryEntry* aRedirectEntry, |
608 | ThreatHit_ThreatSourceType aType) { |
609 | if (NS_WARN_IF(!aRedirectEntry)NS_warn_if_impl(!aRedirectEntry, "!aRedirectEntry", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 609)) { |
610 | return NS_ERROR_INVALID_ARG; |
611 | } |
612 | |
613 | nsresult rv; |
614 | |
615 | nsCOMPtr<nsIPrincipal> principal; |
616 | rv = aRedirectEntry->GetPrincipal(getter_AddRefs(principal)); |
617 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 617); return rv; } } while (false); |
618 | nsCString spec; |
619 | rv = principal->GetExposableSpec(spec); |
620 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 620); return rv; } } while (false); |
621 | auto source = aHit.add_resources(); |
622 | source->set_url(spec.get()); |
623 | source->set_type(aType); |
624 | |
625 | nsCOMPtr<nsIURI> referrer; |
626 | rv = aRedirectEntry->GetReferrerURI(getter_AddRefs(referrer)); |
627 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && referrer) { |
628 | nsCString referrerSpec; |
629 | rv = GetSpecWithoutSensitiveData(referrer, referrerSpec); |
630 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 630); return rv; } } while (false); |
631 | source->set_referrer(referrerSpec.get()); |
632 | } |
633 | |
634 | nsCString remoteIp; |
635 | rv = aRedirectEntry->GetRemoteAddress(remoteIp); |
636 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !remoteIp.IsEmpty()) { |
637 | source->set_remote_ip(remoteIp.get()); |
638 | } |
639 | return NS_OK; |
640 | } |
641 | |
642 | // Add top level tab url and redirect threatsources to threatHit message |
643 | static nsresult AddTabThreatSources(ThreatHit& aHit, nsIChannel* aChannel) { |
644 | if (NS_WARN_IF(!aChannel)NS_warn_if_impl(!aChannel, "!aChannel", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 644)) { |
645 | return NS_ERROR_INVALID_ARG; |
646 | } |
647 | |
648 | nsresult rv; |
649 | nsCOMPtr<mozIDOMWindowProxy> win; |
650 | nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = |
651 | do_GetService(THIRDPARTYUTIL_CONTRACTID"@mozilla.org/thirdpartyutil;1", &rv); |
652 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 652); return rv; } } while (false); |
653 | |
654 | rv = thirdPartyUtil->GetTopWindowForChannel(aChannel, nullptr, |
655 | getter_AddRefs(win)); |
656 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 656); return rv; } } while (false); |
657 | |
658 | auto* pwin = nsPIDOMWindowOuter::From(win); |
659 | nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell(); |
660 | if (!docShell) { |
661 | return NS_OK; |
662 | } |
663 | |
664 | nsCOMPtr<nsIChannel> topChannel; |
665 | docShell->GetCurrentDocumentChannel(getter_AddRefs(topChannel)); |
666 | if (!topChannel) { |
667 | return NS_OK; |
668 | } |
669 | |
670 | nsCOMPtr<nsIURI> uri; |
671 | rv = aChannel->GetURI(getter_AddRefs(uri)); |
672 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 672); return rv; } } while (false); |
673 | |
674 | nsCOMPtr<nsIURI> topUri; |
675 | rv = topChannel->GetURI(getter_AddRefs(topUri)); |
676 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 676); return rv; } } while (false); |
677 | |
678 | bool isTopUri = false; |
679 | rv = topUri->Equals(uri, &isTopUri); |
680 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !isTopUri) { |
681 | nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); |
682 | if (loadInfo->RedirectChain().Length()) { |
683 | AddThreatSourceFromRedirectEntry(aHit, loadInfo->RedirectChain()[0], |
684 | ThreatHit_ThreatSourceType_TAB_RESOURCE); |
685 | } |
686 | } |
687 | |
688 | // Set top level tab_url threat source |
689 | rv = AddThreatSourceFromChannel(aHit, topChannel, |
690 | ThreatHit_ThreatSourceType_TAB_URL); |
691 | Unused << NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv )), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 691); |
692 | |
693 | // Set tab_redirect threat sources if there's any |
694 | nsCOMPtr<nsILoadInfo> topLoadInfo = topChannel->LoadInfo(); |
695 | nsIRedirectHistoryEntry* redirectEntry; |
696 | size_t length = topLoadInfo->RedirectChain().Length(); |
697 | for (size_t i = 0; i < length; i++) { |
698 | redirectEntry = topLoadInfo->RedirectChain()[i]; |
699 | AddThreatSourceFromRedirectEntry(aHit, redirectEntry, |
700 | ThreatHit_ThreatSourceType_TAB_REDIRECT); |
701 | } |
702 | |
703 | return NS_OK; |
704 | } |
705 | |
706 | NS_IMETHODIMPnsresult |
707 | nsUrlClassifierUtils::MakeThreatHitReport(nsIChannel* aChannel, |
708 | const nsACString& aListName, |
709 | const nsACString& aHashBase64, |
710 | nsACString& aRequest) { |
711 | if (NS_WARN_IF(aListName.IsEmpty())NS_warn_if_impl(aListName.IsEmpty(), "aListName.IsEmpty()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 711) || NS_WARN_IF(aHashBase64.IsEmpty())NS_warn_if_impl(aHashBase64.IsEmpty(), "aHashBase64.IsEmpty()" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 711) || |
712 | NS_WARN_IF(!aChannel)NS_warn_if_impl(!aChannel, "!aChannel", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 712)) { |
713 | return NS_ERROR_INVALID_ARG; |
714 | } |
715 | |
716 | ThreatHit hit; |
717 | nsresult rv; |
718 | |
719 | uint32_t threatType; |
720 | rv = ConvertListNameToThreatType(aListName, &threatType); |
721 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 721); return rv; } } while (false); |
722 | hit.set_threat_type(static_cast<ThreatType>(threatType)); |
723 | |
724 | hit.set_platform_type(GetPlatformType()); |
725 | |
726 | nsCString hash; |
727 | rv = Base64Decode(aHashBase64, hash); |
728 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || hash.Length() != COMPLETE_SIZE32) { |
729 | return NS_ERROR_FAILURE; |
730 | } |
731 | |
732 | auto threatEntry = hit.mutable_entry(); |
733 | threatEntry->set_hash(hash.get(), hash.Length()); |
734 | |
735 | // Set matching source |
736 | rv = AddThreatSourceFromChannel(hit, aChannel, |
737 | ThreatHit_ThreatSourceType_MATCHING_URL); |
738 | Unused << NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv )), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 738); |
739 | // Set tab url, tab resource url and redirect sources |
740 | rv = AddTabThreatSources(hit, aChannel); |
741 | Unused << NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv )), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 741); |
742 | |
743 | hit.set_allocated_client_info(CreateClientInfo()); |
744 | |
745 | std::string s; |
746 | hit.SerializeToString(&s); |
747 | |
748 | nsCString out; |
749 | rv = Base64URLEncode(s.size(), reinterpret_cast<const uint8_t*>(s.c_str()), |
750 | Base64URLEncodePaddingPolicy::Include, out); |
751 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 751); return rv; } } while (false); |
752 | |
753 | aRequest = out; |
754 | |
755 | return NS_OK; |
756 | } |
757 | |
758 | static uint32_t DurationToMs(const Duration& aDuration) { |
759 | // Seconds precision is good enough. Ignore nanoseconds like Chrome does. |
760 | return aDuration.seconds() * 1000; |
761 | } |
762 | |
763 | NS_IMETHODIMPnsresult |
764 | nsUrlClassifierUtils::ParseFindFullHashResponseV4( |
765 | const nsACString& aResponse, |
766 | nsIUrlClassifierParseFindFullHashCallback* aCallback) { |
767 | enum CompletionErrorType { |
768 | SUCCESS = 0, |
769 | PARSING_FAILURE = 1, |
770 | UNKNOWN_THREAT_TYPE = 2, |
771 | }; |
772 | |
773 | FindFullHashesResponse r; |
774 | if (!r.ParseFromArray(aResponse.BeginReading(), aResponse.Length())) { |
775 | NS_WARNING("Invalid response")NS_DebugBreak(NS_DEBUG_WARNING, "Invalid response", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 775); |
776 | Telemetry::Accumulate(Telemetry::URLCLASSIFIER_COMPLETION_ERROR, |
777 | PARSING_FAILURE); |
778 | return NS_ERROR_FAILURE; |
779 | } |
780 | |
781 | bool hasUnknownThreatType = false; |
782 | |
783 | for (auto& m : r.matches()) { |
784 | nsCString tableNames; |
785 | nsresult rv = ConvertThreatTypeToListNames(m.threat_type(), tableNames); |
786 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
787 | hasUnknownThreatType = true; |
788 | continue; // Ignore un-convertable threat type. |
789 | } |
790 | auto& hash = m.threat().hash(); |
791 | auto cacheDurationSec = m.cache_duration().seconds(); |
792 | aCallback->OnCompleteHashFound( |
793 | nsDependentCString(hash.c_str(), hash.length()), tableNames, |
794 | cacheDurationSec); |
795 | } |
796 | |
797 | auto minWaitDuration = DurationToMs(r.minimum_wait_duration()); |
798 | auto negCacheDurationSec = r.negative_cache_duration().seconds(); |
799 | |
800 | aCallback->OnResponseParsed(minWaitDuration, negCacheDurationSec); |
801 | |
802 | Telemetry::Accumulate(Telemetry::URLCLASSIFIER_COMPLETION_ERROR, |
803 | hasUnknownThreatType ? UNKNOWN_THREAT_TYPE : SUCCESS); |
804 | return NS_OK; |
805 | } |
806 | |
807 | ////////////////////////////////////////////////////////// |
808 | // nsIObserver |
809 | |
810 | NS_IMETHODIMPnsresult |
811 | nsUrlClassifierUtils::Observe(nsISupports* aSubject, const char* aTopic, |
812 | const char16_t* aData) { |
813 | if (0 == strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID"nsPref:changed")) { |
814 | MutexAutoLock lock(mProviderDictLock); |
815 | return ReadProvidersFromPrefs(mProviderDict); |
816 | } |
817 | |
818 | if (0 == strcmp(aTopic, "xpcom-shutdown-threads")) { |
819 | nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1"); |
820 | NS_ENSURE_TRUE(prefs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(prefs)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefs" ") failed", nullptr , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 820); return NS_ERROR_FAILURE; } } while (false); |
821 | return prefs->RemoveObserver("browser.safebrowsing", this); |
822 | } |
823 | |
824 | return NS_ERROR_UNEXPECTED; |
825 | } |
826 | |
827 | ///////////////////////////////////////////////////////////////////////////// |
828 | // non-interface methods |
829 | |
830 | nsresult nsUrlClassifierUtils::ReadProvidersFromPrefs(ProviderDictType& aDict) { |
831 | MOZ_ASSERT(NS_IsMainThread(),do { static_assert( mozilla::detail::AssertionConditionType< decltype(NS_IsMainThread())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()" " (" "ReadProvidersFromPrefs must be on main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 832); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ") (" "ReadProvidersFromPrefs must be on main thread" ")"); do { *((volatile int*)__null) = 832; __attribute__((nomerge)) :: abort(); } while (false); } } while (false) |
832 | "ReadProvidersFromPrefs must be on main thread")do { static_assert( mozilla::detail::AssertionConditionType< decltype(NS_IsMainThread())>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()" " (" "ReadProvidersFromPrefs must be on main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 832); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()" ") (" "ReadProvidersFromPrefs must be on main thread" ")"); do { *((volatile int*)__null) = 832; __attribute__((nomerge)) :: abort(); } while (false); } } while (false); |
833 | |
834 | nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID"@mozilla.org/preferences-service;1"); |
835 | NS_ENSURE_TRUE(prefs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(prefs)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefs" ") failed", nullptr , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 835); return NS_ERROR_FAILURE; } } while (false); |
836 | nsCOMPtr<nsIPrefBranch> prefBranch; |
837 | nsresult rv = prefs->GetBranch("browser.safebrowsing.provider.", |
838 | getter_AddRefs(prefBranch)); |
839 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 839); return rv; } } while (false); |
840 | |
841 | // We've got a pref branch for "browser.safebrowsing.provider.". |
842 | // Enumerate all children prefs and parse providers. |
843 | nsTArray<nsCString> childArray; |
844 | rv = prefBranch->GetChildList("", childArray); |
845 | 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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp" , 845); return rv; } } while (false); |
846 | |
847 | // Collect providers from childArray. |
848 | nsTHashSet<nsCString> providers; |
849 | for (auto& child : childArray) { |
850 | auto dotPos = child.FindChar('.'); |
851 | if (dotPos < 0) { |
852 | continue; |
853 | } |
854 | |
855 | nsDependentCSubstring provider = Substring(child, 0, dotPos); |
856 | |
857 | providers.Insert(provider); |
858 | } |
859 | |
860 | // Now we have all providers. Check which one owns |aTableName|. |
861 | // e.g. The owning lists of provider "google" is defined in |
862 | // "browser.safebrowsing.provider.google.lists". |
863 | for (const auto& provider : providers) { |
864 | nsPrintfCString owninListsPref("%s.lists", |
865 | nsPromiseFlatCString{provider}.get()); |
866 | |
867 | nsAutoCString owningLists; |
868 | nsresult rv = prefBranch->GetCharPref(owninListsPref.get(), owningLists); |
869 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
870 | continue; |
871 | } |
872 | |
873 | // We've got the owning lists (represented as string) of |provider|. |
874 | // Build the dictionary for the owning list and the current provider. |
875 | nsTArray<nsCString> tables; |
876 | Classifier::SplitTables(owningLists, tables); |
877 | for (auto tableName : tables) { |
878 | aDict.InsertOrUpdate(tableName, MakeUnique<nsCString>(provider)); |
879 | } |
880 | } |
881 | |
882 | return NS_OK; |
883 | } |
884 | |
885 | nsresult nsUrlClassifierUtils::CanonicalizeHostname(const nsACString& hostname, |
886 | nsACString& _retval) { |
887 | nsAutoCString unescaped; |
888 | if (!NS_UnescapeURL(PromiseFlatCStringTPromiseFlatString<char>(hostname).get(), |
889 | PromiseFlatCStringTPromiseFlatString<char>(hostname).Length(), 0, unescaped)) { |
890 | unescaped.Assign(hostname); |
891 | } |
892 | |
893 | nsAutoCString cleaned; |
894 | CleanupHostname(unescaped, cleaned); |
895 | |
896 | nsAutoCString temp; |
897 | ParseIPAddress(cleaned, temp); |
898 | if (!temp.IsEmpty()) { |
899 | cleaned.Assign(temp); |
900 | } |
901 | |
902 | ToLowerCase(cleaned); |
903 | SpecialEncode(cleaned, false, _retval); |
904 | |
905 | return NS_OK; |
906 | } |
907 | |
908 | nsresult nsUrlClassifierUtils::CanonicalizePath(const nsACString& path, |
909 | nsACString& _retval) { |
910 | _retval.Truncate(); |
911 | |
912 | nsAutoCString decodedPath(path); |
913 | nsAutoCString temp; |
914 | while (NS_UnescapeURL(decodedPath.get(), decodedPath.Length(), 0, temp)) { |
915 | decodedPath.Assign(temp); |
916 | temp.Truncate(); |
917 | } |
918 | |
919 | SpecialEncode(decodedPath, true, _retval); |
920 | // XXX: lowercase the path? |
921 | |
922 | return NS_OK; |
923 | } |
924 | |
925 | nsresult nsUrlClassifierUtils::CanonicalizeQuery(const nsACString& query, |
926 | nsACString& _retval) { |
927 | _retval.Truncate(); |
928 | _retval.Append('?'); |
929 | |
930 | // Unescape the query |
931 | nsAutoCString unescaped; |
932 | if (!NS_UnescapeURL(PromiseFlatCStringTPromiseFlatString<char>(query).get(), |
933 | PromiseFlatCStringTPromiseFlatString<char>(query).Length(), 0, unescaped)) { |
934 | unescaped.Assign(query); |
935 | } |
936 | |
937 | // slash folding does not apply to the query parameters, but we need to |
938 | // percent-escape all characters that are <= ASCII 32, >= 127, "#", or "%" |
939 | SpecialEncode(unescaped, false, _retval); |
940 | |
941 | return NS_OK; |
942 | } |
943 | |
944 | void nsUrlClassifierUtils::CleanupHostname(const nsACString& hostname, |
945 | nsACString& _retval) { |
946 | _retval.Truncate(); |
947 | |
948 | const char* curChar = hostname.BeginReading(); |
949 | const char* end = hostname.EndReading(); |
950 | char lastChar = '\0'; |
951 | while (curChar != end) { |
952 | unsigned char c = static_cast<unsigned char>(*curChar); |
953 | if (c == '.' && (lastChar == '\0' || lastChar == '.')) { |
954 | // skip |
955 | } else { |
956 | _retval.Append(*curChar); |
957 | } |
958 | lastChar = c; |
959 | ++curChar; |
960 | } |
961 | |
962 | // cut off trailing dots |
963 | while (_retval.Length() > 0 && _retval[_retval.Length() - 1] == '.') { |
964 | _retval.SetLength(_retval.Length() - 1); |
965 | } |
966 | } |
967 | |
968 | void nsUrlClassifierUtils::ParseIPAddress(const nsACString& host, |
969 | nsACString& _retval) { |
970 | _retval.Truncate(); |
971 | nsACString::const_iterator iter, end; |
972 | host.BeginReading(iter); |
973 | host.EndReading(end); |
974 | |
975 | if (host.Length() <= 15) { |
976 | // The Windows resolver allows a 4-part dotted decimal IP address to |
977 | // have a space followed by any old rubbish, so long as the total length |
978 | // of the string doesn't get above 15 characters. So, "10.192.95.89 xy" |
979 | // is resolved to 10.192.95.89. |
980 | // If the string length is greater than 15 characters, e.g. |
981 | // "10.192.95.89 xy.wildcard.example.com", it will be resolved through |
982 | // DNS. |
983 | |
984 | if (FindCharInReadable(' ', iter, end)) { |
985 | end = iter; |
986 | } |
987 | } |
988 | |
989 | for (host.BeginReading(iter); iter != end; iter++) { |
990 | if (!(mozilla::IsAsciiHexDigit(*iter) || *iter == 'x' || *iter == 'X' || |
991 | *iter == '.')) { |
992 | // not an IP |
993 | return; |
994 | } |
995 | } |
996 | |
997 | host.BeginReading(iter); |
998 | nsTArray<nsCString> parts; |
999 | ParseString(PromiseFlatCStringTPromiseFlatString<char>(Substring(iter, end)), '.', parts); |
1000 | if (parts.Length() > 4) { |
1001 | return; |
1002 | } |
1003 | |
1004 | // If any potentially-octal numbers (start with 0 but not hex) have |
1005 | // non-octal digits, no part of the ip can be in octal |
1006 | // XXX: this came from the old javascript implementation, is it really |
1007 | // supposed to be like this? |
1008 | bool allowOctal = true; |
1009 | uint32_t i; |
1010 | |
1011 | for (i = 0; i < parts.Length(); i++) { |
1012 | const nsCString& part = parts[i]; |
1013 | if (part[0] == '0') { |
1014 | for (uint32_t j = 1; j < part.Length(); j++) { |
1015 | if (part[j] == 'x') { |
1016 | break; |
1017 | } |
1018 | if (part[j] == '8' || part[j] == '9') { |
1019 | allowOctal = false; |
1020 | break; |
1021 | } |
1022 | } |
1023 | } |
1024 | } |
1025 | |
1026 | for (i = 0; i < parts.Length(); i++) { |
1027 | nsAutoCString canonical; |
1028 | |
1029 | if (i == parts.Length() - 1) { |
1030 | CanonicalNum(parts[i], 5 - parts.Length(), allowOctal, canonical); |
1031 | } else { |
1032 | CanonicalNum(parts[i], 1, allowOctal, canonical); |
1033 | } |
1034 | |
1035 | if (canonical.IsEmpty()) { |
1036 | _retval.Truncate(); |
1037 | return; |
1038 | } |
1039 | |
1040 | if (_retval.IsEmpty()) { |
1041 | _retval.Assign(canonical); |
1042 | } else { |
1043 | _retval.Append('.'); |
1044 | _retval.Append(canonical); |
1045 | } |
1046 | } |
1047 | } |
1048 | |
1049 | void nsUrlClassifierUtils::CanonicalNum(const nsACString& num, uint32_t bytes, |
1050 | bool allowOctal, nsACString& _retval) { |
1051 | _retval.Truncate(); |
1052 | |
1053 | if (num.Length() < 1) { |
1054 | return; |
1055 | } |
1056 | |
1057 | uint32_t val; |
1058 | if (allowOctal && IsOctal(num)) { |
1059 | if (PR_sscanf(PromiseFlatCStringTPromiseFlatString<char>(num).get(), "%o", &val) != 1) { |
1060 | return; |
1061 | } |
1062 | } else if (IsDecimal(num)) { |
1063 | if (PR_sscanf(PromiseFlatCStringTPromiseFlatString<char>(num).get(), "%u", &val) != 1) { |
1064 | return; |
1065 | } |
1066 | } else if (IsHex(num)) { |
1067 | if (PR_sscanf(PromiseFlatCStringTPromiseFlatString<char>(num).get(), |
1068 | num[1] == 'X' ? "0X%x" : "0x%x", &val) != 1) { |
1069 | return; |
1070 | } |
1071 | } else { |
1072 | return; |
1073 | } |
1074 | |
1075 | while (bytes--) { |
1076 | char buf[20]; |
1077 | SprintfLiteral(buf, "%u", val & 0xff); |
1078 | if (_retval.IsEmpty()) { |
1079 | _retval.Assign(buf); |
1080 | } else { |
1081 | _retval = nsDependentCString(buf) + "."_ns + _retval; |
1082 | } |
1083 | val >>= 8; |
1084 | } |
1085 | } |
1086 | |
1087 | // This function will encode all "special" characters in typical url |
1088 | // encoding, that is %hh where h is a valid hex digit. It will also fold |
1089 | // any duplicated slashes. |
1090 | bool nsUrlClassifierUtils::SpecialEncode(const nsACString& url, |
1091 | bool foldSlashes, |
1092 | nsACString& _retval) { |
1093 | bool changed = false; |
1094 | const char* curChar = url.BeginReading(); |
1095 | const char* end = url.EndReading(); |
1096 | |
1097 | unsigned char lastChar = '\0'; |
1098 | while (curChar != end) { |
1099 | unsigned char c = static_cast<unsigned char>(*curChar); |
1100 | if (ShouldURLEscape(c)) { |
1101 | _retval.Append('%'); |
1102 | _retval.Append(int_to_hex_digit(c / 16)); |
1103 | _retval.Append(int_to_hex_digit(c % 16)); |
1104 | |
1105 | changed = true; |
1106 | } else if (foldSlashes && (c == '/' && lastChar == '/')) { |
1107 | // skip |
1108 | } else { |
1109 | _retval.Append(*curChar); |
1110 | } |
1111 | lastChar = c; |
1112 | curChar++; |
1113 | } |
1114 | return changed; |
1115 | } |
1116 | |
1117 | bool nsUrlClassifierUtils::ShouldURLEscape(const unsigned char c) const { |
1118 | return c <= 32 || c == '%' || c == '#' || c >= 127; |
1119 | } |
1120 | |
1121 | // moztest- tables are built-in created in LookupCache, they contain hardcoded |
1122 | // url entries in it. moztest tables don't support updates. |
1123 | // static |
1124 | bool nsUrlClassifierUtils::IsMozTestTable(const nsACString& aTableName) { |
1125 | return StringBeginsWith(aTableName, "moztest-"_ns); |
1126 | } |
1127 | |
1128 | // test- tables are used by testcases and can add custom test entries |
1129 | // through update API. |
1130 | // static |
1131 | bool nsUrlClassifierUtils::IsTestTable(const nsACString& aTableName) { |
1132 | return IsMozTestTable(aTableName) || StringBeginsWith(aTableName, "test"_ns); |
1133 | } |
1134 | |
1135 | bool nsUrlClassifierUtils::IsInSafeMode() { |
1136 | static Maybe<bool> sIsInSafeMode; |
1137 | |
1138 | if (!sIsInSafeMode.isSome()) { |
1139 | nsCOMPtr<nsIXULRuntime> appInfo = |
1140 | do_GetService("@mozilla.org/xre/runtime;1"); |
1141 | if (appInfo) { |
1142 | bool inSafeMode = false; |
1143 | appInfo->GetInSafeMode(&inSafeMode); |
1144 | sIsInSafeMode.emplace(inSafeMode); |
1145 | } |
1146 | } |
1147 | |
1148 | return sIsInSafeMode.value(); |
1149 | } |