Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp
Warning:line 445, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_components_places0.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=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/components/places -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/components/places -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/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 /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/components/places -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/build -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -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-deprecated-this-capture -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 -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 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-09-22-115206-3586786-1 -x c++ Unified_cpp_components_places0.cpp
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#include "FaviconHelpers.h"
8
9#include "nsICacheEntry.h"
10#include "nsICachingChannel.h"
11#include "nsIClassOfService.h"
12#include "nsIAsyncVerifyRedirectCallback.h"
13#include "nsIHttpChannel.h"
14#include "nsIPrincipal.h"
15
16#include "nsComponentManagerUtils.h"
17#include "nsNavHistory.h"
18#include "nsFaviconService.h"
19
20#include "mozilla/dom/PlacesFavicon.h"
21#include "mozilla/dom/PlacesObservers.h"
22#include "mozilla/storage.h"
23#include "mozilla/ScopeExit.h"
24#include "mozilla/Telemetry.h"
25#include "mozilla/StaticPrefs_network.h"
26#include "nsNetUtil.h"
27#include "nsPrintfCString.h"
28#include "nsStreamUtils.h"
29#include "nsStringStream.h"
30#include "nsIPrivateBrowsingChannel.h"
31#include "nsISupportsPriority.h"
32#include <algorithm>
33#include <deque>
34#include "mozilla/gfx/2D.h"
35#include "imgIContainer.h"
36#include "ImageOps.h"
37#include "imgIEncoder.h"
38
39using namespace mozilla;
40using namespace mozilla::places;
41using namespace mozilla::storage;
42
43namespace mozilla {
44namespace places {
45
46namespace {
47
48/**
49 * Fetches information about a page from the database.
50 *
51 * @param aDB
52 * Database connection to history tables.
53 * @param _page
54 * Page that should be fetched.
55 */
56nsresult FetchPageInfo(const RefPtr<Database>& aDB, PageData& _page) {
57 MOZ_ASSERT(_page.spec.Length(), "Must have a non-empty spec!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_page.spec.Length())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_page.spec.Length()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("_page.spec.Length()"
" (" "Must have a non-empty spec!" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 57); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_page.spec.Length()"
") (" "Must have a non-empty spec!" ")"); do { *((volatile int
*)__null) = 57; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
58 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 58); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 58; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
59
60 // The subquery finds the bookmarked uri we want to set the icon for,
61 // walking up redirects.
62 nsCString query = nsPrintfCString(
63 "SELECT h.id, pi.id, h.guid, ( "
64 "WITH RECURSIVE "
65 "destinations(visit_type, from_visit, place_id, rev_host, bm) AS ( "
66 "SELECT v.visit_type, v.from_visit, p.id, p.rev_host, b.id "
67 "FROM moz_places p "
68 "LEFT JOIN moz_historyvisits v ON v.place_id = p.id "
69 "LEFT JOIN moz_bookmarks b ON b.fk = p.id "
70 "WHERE p.id = h.id "
71 "UNION "
72 "SELECT src.visit_type, src.from_visit, src.place_id, p.rev_host, b.id "
73 "FROM moz_places p "
74 "JOIN moz_historyvisits src ON src.place_id = p.id "
75 "JOIN destinations dest ON dest.from_visit = src.id AND dest.visit_type "
76 "IN (%d, %d) "
77 "LEFT JOIN moz_bookmarks b ON b.fk = src.place_id "
78 "WHERE instr(p.rev_host, dest.rev_host) = 1 "
79 "OR instr(dest.rev_host, p.rev_host) = 1 "
80 ") "
81 "SELECT url "
82 "FROM moz_places p "
83 "JOIN destinations r ON r.place_id = p.id "
84 "WHERE bm NOTNULL "
85 "LIMIT 1 "
86 "), fixup_url(get_unreversed_host(h.rev_host)) AS host "
87 "FROM moz_places h "
88 "LEFT JOIN moz_pages_w_icons pi ON page_url_hash = hash(:page_url) AND "
89 "page_url = :page_url "
90 "WHERE h.url_hash = hash(:page_url) AND h.url = :page_url",
91 nsINavHistoryService::TRANSITION_REDIRECT_PERMANENT,
92 nsINavHistoryService::TRANSITION_REDIRECT_TEMPORARY);
93
94 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(query);
95 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 95); return NS_ERROR_UNEXPECTED; } } while (false)
;
96 mozStorageStatementScoper scoper(stmt);
97
98 nsresult rv = URIBinder::Bind(stmt, "page_url"_ns, _page.spec);
99 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/places/FaviconHelpers.cpp"
, 99); return rv; } } while (false)
;
100
101 bool hasResult;
102 rv = stmt->ExecuteStep(&hasResult);
103 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/places/FaviconHelpers.cpp"
, 103); return rv; } } while (false)
;
104 if (!hasResult) {
105 // The page does not exist.
106 return NS_ERROR_NOT_AVAILABLE;
107 }
108
109 rv = stmt->GetInt64(0, &_page.placeId);
110 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/places/FaviconHelpers.cpp"
, 110); return rv; } } while (false)
;
111 // May be null, and in such a case this will be 0.
112 _page.id = stmt->AsInt64(1);
113 rv = stmt->GetUTF8String(2, _page.guid);
114 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/places/FaviconHelpers.cpp"
, 114); return rv; } } while (false)
;
115 // Bookmarked url can be nullptr.
116 bool isNull;
117 rv = stmt->GetIsNull(3, &isNull);
118 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/places/FaviconHelpers.cpp"
, 118); return rv; } } while (false)
;
119 // The page could not be bookmarked.
120 if (!isNull) {
121 rv = stmt->GetUTF8String(3, _page.bookmarkedSpec);
122 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/places/FaviconHelpers.cpp"
, 122); return rv; } } while (false)
;
123 }
124
125 if (_page.host.IsEmpty()) {
126 rv = stmt->GetUTF8String(4, _page.host);
127 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 127); return rv; } } while (false)
;
128 }
129
130 if (!_page.canAddToHistory) {
131 // Either history is disabled or the scheme is not supported. In such a
132 // case we want to update the icon only if the page is bookmarked.
133
134 if (_page.bookmarkedSpec.IsEmpty()) {
135 // The page is not bookmarked. Since updating the icon with a disabled
136 // history would be a privacy leak, bail out as if the page did not exist.
137 return NS_ERROR_NOT_AVAILABLE;
138 } else {
139 // The page, or a redirect to it, is bookmarked. If the bookmarked spec
140 // is different from the requested one, use it.
141 if (!_page.bookmarkedSpec.Equals(_page.spec)) {
142 _page.spec = _page.bookmarkedSpec;
143 rv = FetchPageInfo(aDB, _page);
144 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/places/FaviconHelpers.cpp"
, 144); return rv; } } while (false)
;
145 }
146 }
147 }
148
149 return NS_OK;
150}
151
152/**
153 * Stores information about an icon in the database.
154 *
155 * @param aDB
156 * Database connection to history tables.
157 * @param aIcon
158 * Icon that should be stored.
159 * @param aMustReplace
160 * If set to true, the function will bail out with NS_ERROR_NOT_AVAILABLE
161 * if it can't find a previous stored icon to replace.
162 * @note Should be wrapped in a transaction.
163 */
164nsresult SetIconInfo(const RefPtr<Database>& aDB, IconData& aIcon,
165 bool aMustReplace = false) {
166 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 166); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 166; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
167 MOZ_ASSERT(aIcon.payloads.Length() > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aIcon.payloads.Length() > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aIcon.payloads.Length() >
0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aIcon.payloads.Length() > 0", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 167); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aIcon.payloads.Length() > 0"
")"); do { *((volatile int*)__null) = 167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
168 MOZ_ASSERT(!aIcon.spec.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIcon.spec.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIcon.spec.IsEmpty()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!aIcon.spec.IsEmpty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 168); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIcon.spec.IsEmpty()"
")"); do { *((volatile int*)__null) = 168; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
169 MOZ_ASSERT(aIcon.expiration > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aIcon.expiration > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aIcon.expiration > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aIcon.expiration > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aIcon.expiration > 0"
")"); do { *((volatile int*)__null) = 169; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
170
171 // There are multiple cases possible at this point:
172 // 1. We must insert some payloads and no payloads exist in the table. This
173 // would be a straight INSERT.
174 // 2. The table contains the same number of payloads we are inserting. This
175 // would be a straight UPDATE.
176 // 3. The table contains more payloads than we are inserting. This would be
177 // an UPDATE and a DELETE.
178 // 4. The table contains less payloads than we are inserting. This would be
179 // an UPDATE and an INSERT.
180 // We can't just remove all the old entries and insert the new ones, cause
181 // we'd lose the referential integrity with pages. For the same reason we
182 // cannot use INSERT OR REPLACE, since it's implemented as DELETE AND INSERT.
183 // Thus, we follow this strategy:
184 // * SELECT all existing icon ids
185 // * For each payload, either UPDATE OR INSERT reusing icon ids.
186 // * If any previous icon ids is leftover, DELETE it.
187
188 nsCOMPtr<mozIStorageStatement> selectStmt = aDB->GetStatement(
189 "SELECT id FROM moz_icons "
190 "WHERE fixed_icon_url_hash = hash(fixup_url(:url)) "
191 "AND icon_url = :url ");
192 NS_ENSURE_STATE(selectStmt)do { if ((__builtin_expect(!!(!(selectStmt)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "selectStmt" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 192); return NS_ERROR_UNEXPECTED; } } while (false)
;
193 mozStorageStatementScoper scoper(selectStmt);
194 nsresult rv = URIBinder::Bind(selectStmt, "url"_ns, aIcon.spec);
195 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/places/FaviconHelpers.cpp"
, 195); return rv; } } while (false)
;
196 std::deque<int64_t> ids;
197 bool hasResult = false;
198 while (NS_SUCCEEDED(selectStmt->ExecuteStep(&hasResult))((bool)(__builtin_expect(!!(!NS_FAILED_impl(selectStmt->ExecuteStep
(&hasResult))), 1)))
&& hasResult) {
199 int64_t id = selectStmt->AsInt64(0);
200 MOZ_ASSERT(id > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(id > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(id > 0))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("id > 0", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 200); AnnotateMozCrashReason("MOZ_ASSERT" "(" "id > 0" ")"
); do { *((volatile int*)__null) = 200; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
201 ids.push_back(id);
202 }
203 if (aMustReplace && ids.empty()) {
204 return NS_ERROR_NOT_AVAILABLE;
205 }
206
207 nsCOMPtr<mozIStorageStatement> insertStmt = aDB->GetStatement(
208 "INSERT INTO moz_icons "
209 "(icon_url, fixed_icon_url_hash, width, root, expire_ms, data, flags) "
210 "VALUES (:url, hash(fixup_url(:url)), :width, :root, :expire, :data, "
211 ":flags) ");
212 NS_ENSURE_STATE(insertStmt)do { if ((__builtin_expect(!!(!(insertStmt)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "insertStmt" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 212); return NS_ERROR_UNEXPECTED; } } while (false)
;
213 // ReplaceFaviconData may replace data for an already existing icon, and in
214 // that case it won't have the page uri at hand, thus it can't tell if the
215 // icon is a root icon or not. For that reason, never overwrite a root = 1.
216 nsCOMPtr<mozIStorageStatement> updateStmt = aDB->GetStatement(
217 "UPDATE moz_icons SET width = :width, "
218 "expire_ms = :expire, "
219 "data = :data, "
220 "root = (root OR :root), "
221 "flags = :flags "
222 "WHERE id = :id ");
223 NS_ENSURE_STATE(updateStmt)do { if ((__builtin_expect(!!(!(updateStmt)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "updateStmt" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 223); return NS_ERROR_UNEXPECTED; } } while (false)
;
224
225 for (auto& payload : aIcon.payloads) {
226 // Sanity checks.
227 MOZ_ASSERT(payload.mimeType.EqualsLiteral(PNG_MIME_TYPE) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(payload.mimeType.EqualsLiteral("image/png") || payload
.mimeType.EqualsLiteral("image/svg+xml"))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(payload.mimeType.EqualsLiteral
("image/png") || payload.mimeType.EqualsLiteral("image/svg+xml"
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("payload.mimeType.EqualsLiteral(\"image/png\") || payload.mimeType.EqualsLiteral(\"image/svg+xml\")"
" (" "Only png and svg payloads are supported" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 229); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.mimeType.EqualsLiteral(\"image/png\") || payload.mimeType.EqualsLiteral(\"image/svg+xml\")"
") (" "Only png and svg payloads are supported" ")"); do { *
((volatile int*)__null) = 229; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
228 payload.mimeType.EqualsLiteral(SVG_MIME_TYPE),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(payload.mimeType.EqualsLiteral("image/png") || payload
.mimeType.EqualsLiteral("image/svg+xml"))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(payload.mimeType.EqualsLiteral
("image/png") || payload.mimeType.EqualsLiteral("image/svg+xml"
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("payload.mimeType.EqualsLiteral(\"image/png\") || payload.mimeType.EqualsLiteral(\"image/svg+xml\")"
" (" "Only png and svg payloads are supported" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 229); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.mimeType.EqualsLiteral(\"image/png\") || payload.mimeType.EqualsLiteral(\"image/svg+xml\")"
") (" "Only png and svg payloads are supported" ")"); do { *
((volatile int*)__null) = 229; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
229 "Only png and svg payloads are supported")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(payload.mimeType.EqualsLiteral("image/png") || payload
.mimeType.EqualsLiteral("image/svg+xml"))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(payload.mimeType.EqualsLiteral
("image/png") || payload.mimeType.EqualsLiteral("image/svg+xml"
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("payload.mimeType.EqualsLiteral(\"image/png\") || payload.mimeType.EqualsLiteral(\"image/svg+xml\")"
" (" "Only png and svg payloads are supported" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 229); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.mimeType.EqualsLiteral(\"image/png\") || payload.mimeType.EqualsLiteral(\"image/svg+xml\")"
") (" "Only png and svg payloads are supported" ")"); do { *
((volatile int*)__null) = 229; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
230 MOZ_ASSERT(!payload.mimeType.EqualsLiteral(SVG_MIME_TYPE) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!payload.mimeType.EqualsLiteral("image/svg+xml") || payload
.width == (65535))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!payload.mimeType.EqualsLiteral
("image/svg+xml") || payload.width == (65535)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
" (" "SVG payloads should have max width" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 232); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
") (" "SVG payloads should have max width" ")"); do { *((volatile
int*)__null) = 232; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
231 payload.width == UINT16_MAX,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!payload.mimeType.EqualsLiteral("image/svg+xml") || payload
.width == (65535))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!payload.mimeType.EqualsLiteral
("image/svg+xml") || payload.width == (65535)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
" (" "SVG payloads should have max width" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 232); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
") (" "SVG payloads should have max width" ")"); do { *((volatile
int*)__null) = 232; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
232 "SVG payloads should have max width")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!payload.mimeType.EqualsLiteral("image/svg+xml") || payload
.width == (65535))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!payload.mimeType.EqualsLiteral
("image/svg+xml") || payload.width == (65535)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
" (" "SVG payloads should have max width" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 232); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
") (" "SVG payloads should have max width" ")"); do { *((volatile
int*)__null) = 232; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
233 MOZ_ASSERT(payload.width > 0, "Payload should have a width")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(payload.width > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(payload.width > 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("payload.width > 0"
" (" "Payload should have a width" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 233); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.width > 0"
") (" "Payload should have a width" ")"); do { *((volatile int
*)__null) = 233; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
234#ifdef DEBUG1
235 // Done to ensure we fetch the id. See the MOZ_ASSERT below.
236 payload.id = 0;
237#endif
238 if (!ids.empty()) {
239 // Pop the first existing id for reuse.
240 int64_t id = ids.front();
241 ids.pop_front();
242 mozStorageStatementScoper scoper(updateStmt);
243 rv = updateStmt->BindInt64ByName("id"_ns, id);
244 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/places/FaviconHelpers.cpp"
, 244); return rv; } } while (false)
;
245 rv = updateStmt->BindInt32ByName("width"_ns, payload.width);
246 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/places/FaviconHelpers.cpp"
, 246); return rv; } } while (false)
;
247 rv = updateStmt->BindInt64ByName("expire"_ns, aIcon.expiration / 1000);
248 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/places/FaviconHelpers.cpp"
, 248); return rv; } } while (false)
;
249 rv = updateStmt->BindInt32ByName("root"_ns, aIcon.rootIcon);
250 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/places/FaviconHelpers.cpp"
, 250); return rv; } } while (false)
;
251 rv = updateStmt->BindBlobByName("data"_ns, TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
,
252 payload.data.Length());
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, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 253); return rv; } } while (false)
;
254 rv = updateStmt->BindInt32ByName("flags"_ns, aIcon.flags);
255 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/places/FaviconHelpers.cpp"
, 255); return rv; } } while (false)
;
256 rv = updateStmt->Execute();
257 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 257); return rv; } } while (false)
;
258 // Set the new payload id.
259 payload.id = id;
260 } else {
261 // Insert a new entry.
262 mozStorageStatementScoper scoper(insertStmt);
263 rv = URIBinder::Bind(insertStmt, "url"_ns, aIcon.spec);
264 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/places/FaviconHelpers.cpp"
, 264); return rv; } } while (false)
;
265 rv = insertStmt->BindInt32ByName("width"_ns, payload.width);
266 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/places/FaviconHelpers.cpp"
, 266); return rv; } } while (false)
;
267
268 rv = insertStmt->BindInt32ByName("root"_ns, aIcon.rootIcon);
269 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 269); return rv; } } while (false)
;
270 rv = insertStmt->BindInt64ByName("expire"_ns, aIcon.expiration / 1000);
271 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/places/FaviconHelpers.cpp"
, 271); return rv; } } while (false)
;
272 rv = insertStmt->BindBlobByName("data"_ns, TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
,
273 payload.data.Length());
274 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/places/FaviconHelpers.cpp"
, 274); return rv; } } while (false)
;
275 rv = insertStmt->BindInt32ByName("flags"_ns, aIcon.flags);
276 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/places/FaviconHelpers.cpp"
, 276); return rv; } } while (false)
;
277 rv = insertStmt->Execute();
278 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/places/FaviconHelpers.cpp"
, 278); return rv; } } while (false)
;
279 // Set the new payload id.
280 payload.id = nsFaviconService::sLastInsertedIconId;
281 }
282 MOZ_ASSERT(payload.id > 0, "Payload should have an id")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(payload.id > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(payload.id > 0))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("payload.id > 0"
" (" "Payload should have an id" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 282); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.id > 0"
") (" "Payload should have an id" ")"); do { *((volatile int
*)__null) = 282; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
283 }
284
285 if (!ids.empty()) {
286 // Remove any old leftover payload.
287 nsAutoCString sql("DELETE FROM moz_icons WHERE id IN (");
288 for (int64_t id : ids) {
289 sql.AppendInt(id);
290 sql.AppendLiteral(",");
291 }
292 sql.AppendLiteral(" 0)"); // Non-existing id to match the trailing comma.
293 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(sql);
294 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 294); return NS_ERROR_UNEXPECTED; } } while (false)
;
295 mozStorageStatementScoper scoper(stmt);
296 rv = stmt->Execute();
297 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/places/FaviconHelpers.cpp"
, 297); return rv; } } while (false)
;
298 }
299
300 return NS_OK;
301}
302
303/**
304 * Fetches information on a icon url from the database.
305 *
306 * @param aDBConn
307 * Database connection to history tables.
308 * @param aPreferredWidth
309 * The preferred size to fetch.
310 * @param _icon
311 * Icon that should be fetched.
312 */
313nsresult FetchIconInfo(const RefPtr<Database>& aDB, uint16_t aPreferredWidth,
314 IconData& _icon) {
315 MOZ_ASSERT(_icon.spec.Length(), "Must have a non-empty spec!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_icon.spec.Length())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_icon.spec.Length()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("_icon.spec.Length()"
" (" "Must have a non-empty spec!" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 315); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_icon.spec.Length()"
") (" "Must have a non-empty spec!" ")"); do { *((volatile int
*)__null) = 315; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
316 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 316); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 316; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
317
318 if (_icon.status & ICON_STATUS_CACHED1 << 3) {
319 // The icon data has already been set by ReplaceFaviconData.
320 return NS_OK;
321 }
322
323 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(
324 "/* do not warn (bug no: not worth having a compound index) */ "
325 "SELECT id, expire_ms, data, width, root "
326 "FROM moz_icons "
327 "WHERE fixed_icon_url_hash = hash(fixup_url(:url)) "
328 "AND icon_url = :url "
329 "ORDER BY width DESC ");
330 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 330); return NS_ERROR_UNEXPECTED; } } while (false)
;
331 mozStorageStatementScoper scoper(stmt);
332
333 DebugOnly<nsresult> rv = URIBinder::Bind(stmt, "url"_ns, _icon.spec);
334 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 334); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 334; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
335
336 bool hasResult = false;
337 while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult))((bool)(__builtin_expect(!!(!NS_FAILED_impl(stmt->ExecuteStep
(&hasResult))), 1)))
&& hasResult) {
338 IconPayload payload;
339 rv = stmt->GetInt64(0, &payload.id);
340 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 340; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
341
342 // Expiration can be nullptr.
343 bool isNull;
344 rv = stmt->GetIsNull(1, &isNull);
345 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 345); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 345; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
346 if (!isNull) {
347 int64_t expire_ms;
348 rv = stmt->GetInt64(1, &expire_ms);
349 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
350 _icon.expiration = expire_ms * 1000;
351 }
352
353 uint8_t* data;
354 uint32_t dataLen = 0;
355 rv = stmt->GetBlob(2, &dataLen, &data);
356 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 356; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
357 payload.data.Adopt(TO_CHARBUFFER(data)reinterpret_cast<char*>(const_cast<uint8_t*>(data
))
, dataLen);
358
359 int32_t width;
360 rv = stmt->GetInt32(3, &width);
361 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 361; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
362 payload.width = width;
363 if (payload.width == UINT16_MAX(65535)) {
364 payload.mimeType.AssignLiteral(SVG_MIME_TYPE"image/svg+xml");
365 } else {
366 payload.mimeType.AssignLiteral(PNG_MIME_TYPE"image/png");
367 }
368
369 int32_t rootIcon;
370 rv = stmt->GetInt32(4, &rootIcon);
371 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 371); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 371; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
372 _icon.rootIcon = rootIcon;
373
374 if (aPreferredWidth == 0 || _icon.payloads.Length() == 0) {
375 _icon.payloads.AppendElement(payload);
376 } else if (payload.width >= aPreferredWidth) {
377 // Only retain the best matching payload.
378 _icon.payloads.ReplaceElementAt(0, payload);
379 } else {
380 break;
381 }
382 }
383
384 return NS_OK;
385}
386
387nsresult FetchIconPerSpec(const RefPtr<Database>& aDB,
388 const nsACString& aPageSpec,
389 const nsACString& aPageHost, IconData& aIconData,
390 uint16_t aPreferredWidth) {
391 MOZ_ASSERT(!aPageSpec.IsEmpty(), "Page spec must not be empty.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aPageSpec.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aPageSpec.IsEmpty()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!aPageSpec.IsEmpty()"
" (" "Page spec must not be empty." ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 391); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aPageSpec.IsEmpty()"
") (" "Page spec must not be empty." ")"); do { *((volatile int
*)__null) = 391; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
392 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 392; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
393
394 const uint16_t THRESHOLD_WIDTH = 64;
395
396 // This selects both associated and root domain icons, ordered by width,
397 // where an associated icon has priority over a root domain icon.
398 // If the preferred width is less than or equal to 64px, non-rich icons are
399 // prioritized over rich icons by ordering first by `isRich ASC`, then by
400 // width. If the preferred width is greater than 64px, the sorting prioritizes
401 // width, with no preference for rich or non-rich icons. Regardless, note that
402 // while this way we are far more efficient, we lost associations with root
403 // domain icons, so it's possible we'll return one for a specific size when an
404 // associated icon for that size doesn't exist.
405
406 nsCString query = nsPrintfCString(
407 "/* do not warn (bug no: not worth having a compound index) */ "
408 "SELECT width, icon_url, root, (flags & %d) as isRich "
409 "FROM moz_icons i "
410 "JOIN moz_icons_to_pages ON i.id = icon_id "
411 "JOIN moz_pages_w_icons p ON p.id = page_id "
412 "WHERE page_url_hash = hash(:url) AND page_url = :url "
413 "OR (:hash_idx AND page_url_hash = hash(substr(:url, 0, :hash_idx)) "
414 "AND page_url = substr(:url, 0, :hash_idx)) "
415 "UNION ALL "
416 "SELECT width, icon_url, root, (flags & %d) as isRich "
417 "FROM moz_icons i "
418 "WHERE fixed_icon_url_hash = hash(fixup_url(:host) || '/favicon.ico') "
419 "ORDER BY %s width DESC, root ASC",
420 nsIFaviconService::ICONDATA_FLAGS_RICH,
421 nsIFaviconService::ICONDATA_FLAGS_RICH,
422 // Prefer non-rich icons for small sizes (<= 64px).
423 aPreferredWidth <= THRESHOLD_WIDTH ? "isRich ASC, " : "");
424
425 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(query);
426
427 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 427); return NS_ERROR_UNEXPECTED; } } while (false)
;
428 mozStorageStatementScoper scoper(stmt);
429
430 nsresult rv = URIBinder::Bind(stmt, "url"_ns, aPageSpec);
431 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/places/FaviconHelpers.cpp"
, 431); return rv; } } while (false)
;
432 rv = stmt->BindUTF8StringByName("host"_ns, aPageHost);
433 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/places/FaviconHelpers.cpp"
, 433); return rv; } } while (false)
;
434 int32_t hashIdx = PromiseFlatCStringTPromiseFlatString<char>(aPageSpec).RFind("#");
435 rv = stmt->BindInt32ByName("hash_idx"_ns, hashIdx + 1);
436 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/places/FaviconHelpers.cpp"
, 436); return rv; } } while (false)
;
437
438 // Return the biggest icon close to the preferred width. It may be bigger
439 // or smaller if the preferred width isn't found.
440 // Non-rich icons are prioritized over rich ones for preferred widths <= 64px.
441 bool hasResult;
442 int32_t lastWidth = 0;
443 while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult))((bool)(__builtin_expect(!!(!NS_FAILED_impl(stmt->ExecuteStep
(&hasResult))), 1)))
&& hasResult) {
444 int32_t width;
445 rv = stmt->GetInt32(0, &width);
Value stored to 'rv' is never read
446 if (lastWidth == width) {
447 // If we already found an icon for this width, we always prefer the first
448 // icon found, because it's a non-root icon, per the root ASC ordering.
449 continue;
450 }
451
452 int32_t isRich = stmt->AsInt32(3);
453 if (aPreferredWidth <= THRESHOLD_WIDTH && lastWidth > 0 && isRich) {
454 // If we already found an icon, we prefer it to rich icons for small
455 // sizes.
456 break;
457 }
458
459 if (!aIconData.spec.IsEmpty() && width < aPreferredWidth) {
460 // We found the best match, or we already found a match so we don't need
461 // to fallback to the root domain icon.
462 break;
463 }
464 lastWidth = width;
465 rv = stmt->GetUTF8String(1, aIconData.spec);
466 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/places/FaviconHelpers.cpp"
, 466); return rv; } } while (false)
;
467 }
468
469 return NS_OK;
470}
471
472/**
473 * Tries to compute the expiration time for a icon from the channel.
474 *
475 * @param aChannel
476 * The network channel used to fetch the icon.
477 * @return a valid expiration value for the fetched icon.
478 */
479PRTime GetExpirationTimeFromChannel(nsIChannel* aChannel) {
480 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 480; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
481
482 // Attempt to get an expiration time from the cache. If this fails, we'll
483 // make one up.
484 PRTime now = PR_Now();
485 PRTime expiration = -1;
486 nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aChannel);
487 if (cachingChannel) {
488 nsCOMPtr<nsISupports> cacheToken;
489 nsresult rv = cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
490 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
491 nsCOMPtr<nsICacheEntry> cacheEntry = do_QueryInterface(cacheToken);
492 uint32_t seconds;
493 rv = cacheEntry->GetExpirationTime(&seconds);
494 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
495 // Set the expiration, but make sure we honor our cap.
496 expiration = now + std::min((PRTime)seconds * PR_USEC_PER_SEC1000000L,
497 MAX_FAVICON_EXPIRATION((PRTime)7 * 24 * 60 * 60 * 1000000L));
498 }
499 }
500 }
501 // If we did not obtain a time from the cache, use the cap value.
502 return expiration < now + MIN_FAVICON_EXPIRATION((PRTime)1 * 24 * 60 * 60 * 1000000L)
503 ? now + MAX_FAVICON_EXPIRATION((PRTime)7 * 24 * 60 * 60 * 1000000L)
504 : expiration;
505}
506
507} // namespace
508
509////////////////////////////////////////////////////////////////////////////////
510//// AsyncFetchAndSetIconForPage
511
512NS_IMPL_ISUPPORTS_INHERITED(AsyncFetchAndSetIconForPage, Runnable,nsresult AsyncFetchAndSetIconForPage::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/places/FaviconHelpers.cpp"
, 514); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<AsyncFetchAndSetIconForPage, nsIStreamListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamListener
*>((AsyncFetchAndSetIconForPage*)0x1000)) - reinterpret_cast
<char*>((AsyncFetchAndSetIconForPage*)0x1000))}, {&
mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, nsIInterfaceRequestor>, int32_t( reinterpret_cast<char
*>(static_cast<nsIInterfaceRequestor*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)0x1000))}, {&mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, nsIChannelEventSink>, int32_t( reinterpret_cast<char*
>(static_cast<nsIChannelEventSink*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)0x1000))}, {&mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, mozIPlacesPendingOperation>, int32_t( reinterpret_cast<
char*>(static_cast<mozIPlacesPendingOperation*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)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); if (((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)
), 1)))) return rv; return Runnable::QueryInterface(aIID, aInstancePtr
); } MozExternalRefCountType AsyncFetchAndSetIconForPage::AddRef
(void) { static_assert(!std::is_destructible_v<AsyncFetchAndSetIconForPage
>, "Reference-counted class " "AsyncFetchAndSetIconForPage"
" should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = Runnable::AddRef(); if constexpr (::mozilla::
detail::ShouldLogInheritedRefcnt<AsyncFetchAndSetIconForPage
>) { NS_LogAddRef((this), (r), ("AsyncFetchAndSetIconForPage"
), (uint32_t)(sizeof(*this))); } return r; } MozExternalRefCountType
AsyncFetchAndSetIconForPage::Release(void) { nsrefcnt r = Runnable
::Release(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt
<AsyncFetchAndSetIconForPage>) { NS_LogRelease((this), (
r), ("AsyncFetchAndSetIconForPage")); } return r; }
513 nsIStreamListener, nsIInterfaceRequestor,nsresult AsyncFetchAndSetIconForPage::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/places/FaviconHelpers.cpp"
, 514); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<AsyncFetchAndSetIconForPage, nsIStreamListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamListener
*>((AsyncFetchAndSetIconForPage*)0x1000)) - reinterpret_cast
<char*>((AsyncFetchAndSetIconForPage*)0x1000))}, {&
mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, nsIInterfaceRequestor>, int32_t( reinterpret_cast<char
*>(static_cast<nsIInterfaceRequestor*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)0x1000))}, {&mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, nsIChannelEventSink>, int32_t( reinterpret_cast<char*
>(static_cast<nsIChannelEventSink*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)0x1000))}, {&mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, mozIPlacesPendingOperation>, int32_t( reinterpret_cast<
char*>(static_cast<mozIPlacesPendingOperation*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)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); if (((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)
), 1)))) return rv; return Runnable::QueryInterface(aIID, aInstancePtr
); } MozExternalRefCountType AsyncFetchAndSetIconForPage::AddRef
(void) { static_assert(!std::is_destructible_v<AsyncFetchAndSetIconForPage
>, "Reference-counted class " "AsyncFetchAndSetIconForPage"
" should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = Runnable::AddRef(); if constexpr (::mozilla::
detail::ShouldLogInheritedRefcnt<AsyncFetchAndSetIconForPage
>) { NS_LogAddRef((this), (r), ("AsyncFetchAndSetIconForPage"
), (uint32_t)(sizeof(*this))); } return r; } MozExternalRefCountType
AsyncFetchAndSetIconForPage::Release(void) { nsrefcnt r = Runnable
::Release(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt
<AsyncFetchAndSetIconForPage>) { NS_LogRelease((this), (
r), ("AsyncFetchAndSetIconForPage")); } return r; }
514 nsIChannelEventSink, mozIPlacesPendingOperation)nsresult AsyncFetchAndSetIconForPage::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/places/FaviconHelpers.cpp"
, 514); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(4 > 0, "Need more arguments to NS_INTERFACE_TABLE_INHERITED"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<AsyncFetchAndSetIconForPage, nsIStreamListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamListener
*>((AsyncFetchAndSetIconForPage*)0x1000)) - reinterpret_cast
<char*>((AsyncFetchAndSetIconForPage*)0x1000))}, {&
mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, nsIInterfaceRequestor>, int32_t( reinterpret_cast<char
*>(static_cast<nsIInterfaceRequestor*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)0x1000))}, {&mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, nsIChannelEventSink>, int32_t( reinterpret_cast<char*
>(static_cast<nsIChannelEventSink*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)0x1000))}, {&mozilla::detail::kImplementedIID<AsyncFetchAndSetIconForPage
, mozIPlacesPendingOperation>, int32_t( reinterpret_cast<
char*>(static_cast<mozIPlacesPendingOperation*>((AsyncFetchAndSetIconForPage
*)0x1000)) - reinterpret_cast<char*>((AsyncFetchAndSetIconForPage
*)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); if (((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)
), 1)))) return rv; return Runnable::QueryInterface(aIID, aInstancePtr
); } MozExternalRefCountType AsyncFetchAndSetIconForPage::AddRef
(void) { static_assert(!std::is_destructible_v<AsyncFetchAndSetIconForPage
>, "Reference-counted class " "AsyncFetchAndSetIconForPage"
" should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = Runnable::AddRef(); if constexpr (::mozilla::
detail::ShouldLogInheritedRefcnt<AsyncFetchAndSetIconForPage
>) { NS_LogAddRef((this), (r), ("AsyncFetchAndSetIconForPage"
), (uint32_t)(sizeof(*this))); } return r; } MozExternalRefCountType
AsyncFetchAndSetIconForPage::Release(void) { nsrefcnt r = Runnable
::Release(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt
<AsyncFetchAndSetIconForPage>) { NS_LogRelease((this), (
r), ("AsyncFetchAndSetIconForPage")); } return r; }
515
516AsyncFetchAndSetIconForPage::AsyncFetchAndSetIconForPage(
517 IconData& aIcon, PageData& aPage, bool aFaviconLoadPrivate,
518 nsIFaviconDataCallback* aCallback, nsIPrincipal* aLoadingPrincipal,
519 uint64_t aRequestContextID)
520 : Runnable("places::AsyncFetchAndSetIconForPage"),
521 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
522 "AsyncFetchAndSetIconForPage::mCallback", aCallback)),
523 mIcon(aIcon),
524 mPage(aPage),
525 mFaviconLoadPrivate(aFaviconLoadPrivate),
526 mLoadingPrincipal(new nsMainThreadPtrHolder<nsIPrincipal>(
527 "AsyncFetchAndSetIconForPage::mLoadingPrincipal", aLoadingPrincipal)),
528 mCanceled(false),
529 mRequestContextID(aRequestContextID) {
530 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 530); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 530; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
531}
532
533NS_IMETHODIMPnsresult
534AsyncFetchAndSetIconForPage::Run() {
535 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 535; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
536
537 // Try to fetch the icon from the database.
538 RefPtr<Database> DB = Database::GetDatabase();
539 NS_ENSURE_STATE(DB)do { if ((__builtin_expect(!!(!(DB)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "DB" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 539); return NS_ERROR_UNEXPECTED; } } while (false)
;
540 nsresult rv = FetchIconInfo(DB, 0, mIcon);
541 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/places/FaviconHelpers.cpp"
, 541); return rv; } } while (false)
;
542
543 bool isInvalidIcon = !mIcon.payloads.Length() || PR_Now() > mIcon.expiration;
544 bool fetchIconFromNetwork =
545 mIcon.fetchMode == FETCH_ALWAYS ||
546 (mIcon.fetchMode == FETCH_IF_MISSING && isInvalidIcon);
547
548 // Check if we can associate the icon to this page.
549 rv = FetchPageInfo(DB, mPage);
550 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
551 if (rv == NS_ERROR_NOT_AVAILABLE) {
552 // We have never seen this page. If we can add the page to history,
553 // we will try to do it later, otherwise just bail out.
554 if (!mPage.canAddToHistory) {
555 return NS_OK;
556 }
557 }
558 return rv;
559 }
560
561 if (!fetchIconFromNetwork) {
562 // There is already a valid icon or we don't want to fetch a new one,
563 // directly proceed with association.
564 RefPtr<AsyncAssociateIconToPage> event =
565 new AsyncAssociateIconToPage(mIcon, mPage, mCallback);
566 // We're already on the async thread.
567 return event->Run();
568 }
569
570 // Fetch the icon from the network, the request starts from the main-thread.
571 // When done this will associate the icon to the page and notify.
572 nsCOMPtr<nsIRunnable> event =
573 NewRunnableMethod("places::AsyncFetchAndSetIconForPage::FetchFromNetwork",
574 this, &AsyncFetchAndSetIconForPage::FetchFromNetwork);
575 return NS_DispatchToMainThread(event);
576}
577
578nsresult AsyncFetchAndSetIconForPage::FetchFromNetwork() {
579 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 579); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 579; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
580
581 if (mCanceled) {
582 return NS_OK;
583 }
584
585 // Ensure data is cleared, since it's going to be overwritten.
586 mIcon.payloads.Clear();
587
588 IconPayload payload;
589 mIcon.payloads.AppendElement(payload);
590
591 nsCOMPtr<nsIURI> iconURI;
592 nsresult rv = NS_NewURI(getter_AddRefs(iconURI), mIcon.spec);
593 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/places/FaviconHelpers.cpp"
, 593); return rv; } } while (false)
;
594 nsCOMPtr<nsIChannel> channel;
595 rv = NS_NewChannel(getter_AddRefs(channel), iconURI, mLoadingPrincipal,
596 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT |
597 nsILoadInfo::SEC_ALLOW_CHROME |
598 nsILoadInfo::SEC_DISALLOW_SCRIPT,
599 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON);
600
601 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/places/FaviconHelpers.cpp"
, 601); return rv; } } while (false)
;
602 nsCOMPtr<nsIInterfaceRequestor> listenerRequestor =
603 do_QueryInterface(reinterpret_cast<nsISupports*>(this));
604 NS_ENSURE_STATE(listenerRequestor)do { if ((__builtin_expect(!!(!(listenerRequestor)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "listenerRequestor" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 604); return NS_ERROR_UNEXPECTED; } } while (false)
;
605 rv = channel->SetNotificationCallbacks(listenerRequestor);
606 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/places/FaviconHelpers.cpp"
, 606); return rv; } } while (false)
;
607 nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(channel);
608 if (pbChannel) {
609 rv = pbChannel->SetPrivate(mFaviconLoadPrivate);
610 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/places/FaviconHelpers.cpp"
, 610); return rv; } } while (false)
;
611 }
612
613 nsCOMPtr<nsISupportsPriority> priorityChannel = do_QueryInterface(channel);
614 if (priorityChannel) {
615 priorityChannel->AdjustPriority(nsISupportsPriority::PRIORITY_LOWEST);
616 }
617
618 if (StaticPrefs::network_http_tailing_enabled()) {
619 nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel);
620 if (cos) {
621 cos->AddClassFlags(nsIClassOfService::Tail |
622 nsIClassOfService::Throttleable);
623 }
624
625 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
626 if (httpChannel) {
627 Unused << httpChannel->SetRequestContextID(mRequestContextID);
628 }
629 }
630
631 rv = channel->AsyncOpen(this);
632 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
633 mRequest = channel;
634 }
635 return rv;
636}
637
638NS_IMETHODIMPnsresult
639AsyncFetchAndSetIconForPage::Cancel() {
640 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 640); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 640; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
641 if (mCanceled) {
642 return NS_ERROR_UNEXPECTED;
643 }
644 mCanceled = true;
645 if (mRequest) {
646 mRequest->CancelWithReason(NS_BINDING_ABORTED,
647 "AsyncFetchAndSetIconForPage::Cancel"_ns);
648 }
649 return NS_OK;
650}
651
652NS_IMETHODIMPnsresult
653AsyncFetchAndSetIconForPage::OnStartRequest(nsIRequest* aRequest) {
654 // mRequest should already be set from ::FetchFromNetwork, but in the case of
655 // a redirect we might get a new request, and we should make sure we keep a
656 // reference to the most current request.
657 mRequest = aRequest;
658 if (mCanceled) {
659 mRequest->Cancel(NS_BINDING_ABORTED);
660 }
661 // Don't store icons responding with Cache-Control: no-store, but always
662 // allow root domain icons.
663 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
664 if (httpChannel) {
665 bool isNoStore;
666 nsAutoCString path;
667 nsCOMPtr<nsIURI> uri;
668 if (NS_SUCCEEDED(httpChannel->GetURI(getter_AddRefs(uri)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetURI
(getter_AddRefs(uri)))), 1)))
&&
669 NS_SUCCEEDED(uri->GetFilePath(path))((bool)(__builtin_expect(!!(!NS_FAILED_impl(uri->GetFilePath
(path))), 1)))
&&
670 !path.EqualsLiteral("/favicon.ico") &&
671 NS_SUCCEEDED(httpChannel->IsNoStoreResponse(&isNoStore))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->IsNoStoreResponse
(&isNoStore))), 1)))
&& isNoStore) {
672 // Abandon the network fetch.
673 mRequest->CancelWithReason(
674 NS_BINDING_ABORTED, "AsyncFetchAndSetIconForPage::OnStartRequest"_ns);
675 }
676 }
677 return NS_OK;
678}
679
680NS_IMETHODIMPnsresult
681AsyncFetchAndSetIconForPage::OnDataAvailable(nsIRequest* aRequest,
682 nsIInputStream* aInputStream,
683 uint64_t aOffset,
684 uint32_t aCount) {
685 MOZ_ASSERT(mIcon.payloads.Length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mIcon.payloads.Length() == 1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mIcon.payloads.Length() == 1
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mIcon.payloads.Length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIcon.payloads.Length() == 1"
")"); do { *((volatile int*)__null) = 685; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
686 // Limit downloads to 500KB.
687 const size_t kMaxDownloadSize = 500 * 1024;
688 if (mIcon.payloads[0].data.Length() + aCount > kMaxDownloadSize) {
689 mIcon.payloads.Clear();
690 return NS_ERROR_FILE_TOO_BIG;
691 }
692
693 nsAutoCString buffer;
694 nsresult rv = NS_ConsumeStream(aInputStream, aCount, buffer);
695 if (rv != NS_BASE_STREAM_WOULD_BLOCK && NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
696 return rv;
697 }
698
699 if (!mIcon.payloads[0].data.Append(buffer, fallible)) {
700 mIcon.payloads.Clear();
701 return NS_ERROR_OUT_OF_MEMORY;
702 }
703
704 return NS_OK;
705}
706
707NS_IMETHODIMPnsresult
708AsyncFetchAndSetIconForPage::GetInterface(const nsIID& uuid, void** aResult) {
709 return QueryInterface(uuid, aResult);
710}
711
712NS_IMETHODIMPnsresult
713AsyncFetchAndSetIconForPage::AsyncOnChannelRedirect(
714 nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
715 nsIAsyncVerifyRedirectCallback* cb) {
716 // If we've been canceled, stop the redirect with NS_BINDING_ABORTED, and
717 // handle the cancel on the original channel.
718 (void)cb->OnRedirectVerifyCallback(mCanceled ? NS_BINDING_ABORTED : NS_OK);
719 return NS_OK;
720}
721
722NS_IMETHODIMPnsresult
723AsyncFetchAndSetIconForPage::OnStopRequest(nsIRequest* aRequest,
724 nsresult aStatusCode) {
725 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 725); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 725; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
726
727 // Don't need to track this anymore.
728 mRequest = nullptr;
729 if (mCanceled) {
730 return NS_OK;
731 }
732
733 nsFaviconService* favicons = nsFaviconService::GetFaviconService();
734 NS_ENSURE_STATE(favicons)do { if ((__builtin_expect(!!(!(favicons)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "favicons" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 734); return NS_ERROR_UNEXPECTED; } } while (false)
;
735
736 nsresult rv;
737
738 // If fetching the icon failed, bail out.
739 if (NS_FAILED(aStatusCode)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatusCode)), 0))
)
|| mIcon.payloads.Length() == 0) {
740 return NS_OK;
741 }
742
743 nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
744 // aRequest should always QI to nsIChannel.
745 MOZ_ASSERT(channel)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(channel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(channel))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("channel", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 745); AnnotateMozCrashReason("MOZ_ASSERT" "(" "channel" ")"
); do { *((volatile int*)__null) = 745; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
746
747 MOZ_ASSERT(mIcon.payloads.Length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mIcon.payloads.Length() == 1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mIcon.payloads.Length() == 1
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mIcon.payloads.Length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 747); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIcon.payloads.Length() == 1"
")"); do { *((volatile int*)__null) = 747; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
748 IconPayload& payload = mIcon.payloads[0];
749
750 nsAutoCString contentType;
751 channel->GetContentType(contentType);
752 // Bug 366324 - We don't want to sniff for SVG, so rely on server-specified
753 // type.
754 if (contentType.EqualsLiteral(SVG_MIME_TYPE"image/svg+xml")) {
755 payload.mimeType.AssignLiteral(SVG_MIME_TYPE"image/svg+xml");
756 payload.width = UINT16_MAX(65535);
757 } else {
758 NS_SniffContent(NS_DATA_SNIFFER_CATEGORY"content-sniffing-services", aRequest,
759 TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
, payload.data.Length(),
760 payload.mimeType);
761 }
762
763 // If the icon does not have a valid MIME type, bail out.
764 if (payload.mimeType.IsEmpty()) {
765 return NS_OK;
766 }
767
768 mIcon.expiration = GetExpirationTimeFromChannel(channel);
769
770 // Telemetry probes to measure the favicon file sizes for each different file
771 // type. This allow us to measure common file sizes while also observing each
772 // type popularity.
773 if (payload.mimeType.EqualsLiteral(PNG_MIME_TYPE"image/png")) {
774 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_PNG_SIZES,
775 payload.data.Length());
776 } else if (payload.mimeType.EqualsLiteral("image/x-icon") ||
777 payload.mimeType.EqualsLiteral("image/vnd.microsoft.icon")) {
778 Telemetry::Accumulate(mozilla::Telemetry::PLACES_FAVICON_ICO_SIZES,
779 payload.data.Length());
780 } else if (payload.mimeType.EqualsLiteral("image/jpeg") ||
781 payload.mimeType.EqualsLiteral("image/pjpeg")) {
782 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_JPEG_SIZES,
783 payload.data.Length());
784 } else if (payload.mimeType.EqualsLiteral("image/gif")) {
785 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_GIF_SIZES,
786 payload.data.Length());
787 } else if (payload.mimeType.EqualsLiteral("image/bmp") ||
788 payload.mimeType.EqualsLiteral("image/x-windows-bmp")) {
789 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_BMP_SIZES,
790 payload.data.Length());
791 } else if (payload.mimeType.EqualsLiteral(SVG_MIME_TYPE"image/svg+xml")) {
792 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_SVG_SIZES,
793 payload.data.Length());
794 } else {
795 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_OTHER_SIZES,
796 payload.data.Length());
797 }
798
799 rv = favicons->OptimizeIconSizes(mIcon);
800 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/places/FaviconHelpers.cpp"
, 800); return rv; } } while (false)
;
801
802 mIcon.status = ICON_STATUS_CHANGED1 << 0;
803
804 RefPtr<Database> DB = Database::GetDatabase();
805 NS_ENSURE_STATE(DB)do { if ((__builtin_expect(!!(!(DB)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "DB" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 805); return NS_ERROR_UNEXPECTED; } } while (false)
;
806 RefPtr<AsyncAssociateIconToPage> event =
807 new AsyncAssociateIconToPage(mIcon, mPage, mCallback);
808 DB->DispatchToAsyncThread(event);
809
810 return NS_OK;
811}
812
813////////////////////////////////////////////////////////////////////////////////
814//// AsyncAssociateIconToPage
815
816AsyncAssociateIconToPage::AsyncAssociateIconToPage(
817 const IconData& aIcon, const PageData& aPage,
818 const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback)
819 : Runnable("places::AsyncAssociateIconToPage"),
820 mCallback(aCallback),
821 mIcon(aIcon),
822 mPage(aPage) {
823 // May be created in both threads.
824}
825
826NS_IMETHODIMPnsresult
827AsyncAssociateIconToPage::Run() {
828 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 828); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 828; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
829 MOZ_ASSERT(!mPage.guid.IsEmpty(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPage.guid.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPage.guid.IsEmpty()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mPage.guid.IsEmpty()"
" (" "Page info should have been fetched already" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 830); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPage.guid.IsEmpty()"
") (" "Page info should have been fetched already" ")"); do {
*((volatile int*)__null) = 830; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
830 "Page info should have been fetched already")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPage.guid.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPage.guid.IsEmpty()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mPage.guid.IsEmpty()"
" (" "Page info should have been fetched already" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 830); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPage.guid.IsEmpty()"
") (" "Page info should have been fetched already" ")"); do {
*((volatile int*)__null) = 830; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
831 MOZ_ASSERT(mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty()" " ("
"The page should be addable to history or a bookmark" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 832); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty()"
") (" "The page should be addable to history or a bookmark" ")"
); do { *((volatile int*)__null) = 832; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
832 "The page should be addable to history or a bookmark")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty()" " ("
"The page should be addable to history or a bookmark" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 832); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty()"
") (" "The page should be addable to history or a bookmark" ")"
); do { *((volatile int*)__null) = 832; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
833
834 bool shouldUpdateIcon = mIcon.status & ICON_STATUS_CHANGED1 << 0;
835 if (!shouldUpdateIcon) {
836 for (const auto& payload : mIcon.payloads) {
837 // If the entry is missing from the database, we should add it.
838 if (payload.id == 0) {
839 shouldUpdateIcon = true;
840 break;
841 }
842 }
843 }
844
845 RefPtr<Database> DB = Database::GetDatabase();
846 NS_ENSURE_STATE(DB)do { if ((__builtin_expect(!!(!(DB)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "DB" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 846); return NS_ERROR_UNEXPECTED; } } while (false)
;
847
848 mozStorageTransaction transaction(
849 DB->MainConn(), false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
850
851 // XXX Handle the error, bug 1696133.
852 Unused << NS_WARN_IF(NS_FAILED(transaction.Start()))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(transaction
.Start())), 0))), "NS_FAILED(transaction.Start())", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 852)
;
853
854 nsresult rv;
855 if (shouldUpdateIcon) {
856 rv = SetIconInfo(DB, mIcon);
857 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
858 (void)transaction.Commit();
859 return rv;
860 }
861
862 mIcon.status = (mIcon.status & ~(ICON_STATUS_CACHED1 << 3)) | ICON_STATUS_SAVED1 << 1;
863 }
864
865 // If the page does not have an id, don't try to insert a new one, cause we
866 // don't know where the page comes from. Not doing so we may end adding
867 // a page that otherwise we'd explicitly ignore, like a POST or an error page.
868 if (mPage.placeId == 0) {
869 rv = transaction.Commit();
870 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/places/FaviconHelpers.cpp"
, 870); return rv; } } while (false)
;
871 return NS_OK;
872 }
873
874 // Expire old favicons to keep up with website changes. Associated icons must
875 // be expired also when storing a root favicon, because a page may change to
876 // only have a root favicon.
877 // Note that here we could also be in the process of adding further payloads
878 // to a page, and we don't want to expire just added payloads. For this
879 // reason we only remove expired payloads.
880 // Oprhan icons are not removed at this time because it'd be expensive. The
881 // privacy implications are limited, since history removal methods also expire
882 // orphan icons.
883 if (mPage.id > 0) {
884 nsCOMPtr<mozIStorageStatement> stmt;
885 stmt = DB->GetStatement(
886 "DELETE FROM moz_icons_to_pages "
887 "WHERE page_id = :page_id "
888 "AND expire_ms < strftime('%s','now','localtime','utc') * 1000 ");
889 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 889); return NS_ERROR_UNEXPECTED; } } while (false)
;
890 mozStorageStatementScoper scoper(stmt);
891 rv = stmt->BindInt64ByName("page_id"_ns, mPage.id);
892 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/places/FaviconHelpers.cpp"
, 892); return rv; } } while (false)
;
893 rv = stmt->Execute();
894 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/places/FaviconHelpers.cpp"
, 894); return rv; } } while (false)
;
895 }
896
897 // Don't associate pages to root domain icons, since those will be returned
898 // regardless. This saves a lot of work and database space since we don't
899 // need to store urls and relations.
900 // Though, this is possible only if both the page and the icon have the same
901 // host, otherwise we couldn't relate them.
902 if (!mIcon.rootIcon || !mIcon.host.Equals(mPage.host)) {
903 // The page may have associated payloads already, and those could have to be
904 // expired. For example at a certain point a page could decide to stop
905 // serving its usual 16px and 32px pngs, and use an svg instead. On the
906 // other side, we could also be in the process of adding more payloads to
907 // this page, and we should not expire the payloads we just added. For this,
908 // we use the expiration field as an indicator and remove relations based on
909 // it being elapsed. We don't remove orphan icons at this time since it
910 // would have a cost. The privacy hit is limited since history removal
911 // methods already expire orphan icons.
912 if (mPage.id == 0) {
913 // We need to create the page entry.
914 nsCOMPtr<mozIStorageStatement> stmt;
915 stmt = DB->GetStatement(
916 "INSERT OR IGNORE INTO moz_pages_w_icons (page_url, page_url_hash) "
917 "VALUES (:page_url, hash(:page_url)) ");
918 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 918); return NS_ERROR_UNEXPECTED; } } while (false)
;
919 mozStorageStatementScoper scoper(stmt);
920 rv = URIBinder::Bind(stmt, "page_url"_ns, mPage.spec);
921 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/places/FaviconHelpers.cpp"
, 921); return rv; } } while (false)
;
922 rv = stmt->Execute();
923 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/places/FaviconHelpers.cpp"
, 923); return rv; } } while (false)
;
924 }
925
926 // Then we can create the relations.
927 nsCOMPtr<mozIStorageStatement> stmt;
928 stmt = DB->GetStatement(
929 "INSERT INTO moz_icons_to_pages (page_id, icon_id, expire_ms) "
930 "VALUES ((SELECT id from moz_pages_w_icons WHERE page_url_hash = "
931 "hash(:page_url) AND page_url = :page_url), "
932 ":icon_id, :expire) "
933 "ON CONFLICT(page_id, icon_id) DO "
934 "UPDATE SET expire_ms = :expire ");
935 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 935); return NS_ERROR_UNEXPECTED; } } while (false)
;
936
937 // For some reason using BindingParamsArray here fails execution, so we must
938 // execute the statements one by one.
939 // In the future we may want to investigate the reasons, sounds like related
940 // to contraints.
941 for (const auto& payload : mIcon.payloads) {
942 mozStorageStatementScoper scoper(stmt);
943 nsCOMPtr<mozIStorageBindingParams> params;
944 rv = URIBinder::Bind(stmt, "page_url"_ns, mPage.spec);
945 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/places/FaviconHelpers.cpp"
, 945); return rv; } } while (false)
;
946 rv = stmt->BindInt64ByName("icon_id"_ns, payload.id);
947 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/places/FaviconHelpers.cpp"
, 947); return rv; } } while (false)
;
948 rv = stmt->BindInt64ByName("expire"_ns, mIcon.expiration / 1000);
949 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/places/FaviconHelpers.cpp"
, 949); return rv; } } while (false)
;
950 rv = stmt->Execute();
951 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/places/FaviconHelpers.cpp"
, 951); return rv; } } while (false)
;
952 }
953 }
954
955 mIcon.status |= ICON_STATUS_ASSOCIATED1 << 2;
956
957 rv = transaction.Commit();
958 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/places/FaviconHelpers.cpp"
, 958); return rv; } } while (false)
;
959
960 // Finally, dispatch an event to the main thread to notify observers.
961 nsCOMPtr<nsIRunnable> event =
962 new NotifyIconObservers(mIcon, mPage, mCallback);
963 rv = NS_DispatchToMainThread(event);
964 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/places/FaviconHelpers.cpp"
, 964); return rv; } } while (false)
;
965
966 // If there is a bookmarked page that redirects to this one, try to update its
967 // icon as well.
968 if (!mPage.bookmarkedSpec.IsEmpty() &&
969 !mPage.bookmarkedSpec.Equals(mPage.spec)) {
970 // Create a new page struct to avoid polluting it with old data.
971 PageData bookmarkedPage;
972 bookmarkedPage.spec = mPage.bookmarkedSpec;
973 RefPtr<Database> DB = Database::GetDatabase();
974 if (DB && NS_SUCCEEDED(FetchPageInfo(DB, bookmarkedPage))((bool)(__builtin_expect(!!(!NS_FAILED_impl(FetchPageInfo(DB,
bookmarkedPage))), 1)))
) {
975 // This will be silent, so be sure to not pass in the current callback.
976 nsMainThreadPtrHandle<nsIFaviconDataCallback> nullCallback;
977 RefPtr<AsyncAssociateIconToPage> event =
978 new AsyncAssociateIconToPage(mIcon, bookmarkedPage, nullCallback);
979 Unused << event->Run();
980 }
981 }
982
983 return NS_OK;
984}
985
986////////////////////////////////////////////////////////////////////////////////
987//// AsyncSetIconForPage
988
989AsyncSetIconForPage::AsyncSetIconForPage(const IconData& aIcon,
990 const PageData& aPage,
991 PlacesCompletionCallback* aCallback)
992 : Runnable("places::AsyncSetIconForPage"),
993 mCallback(new nsMainThreadPtrHolder<PlacesCompletionCallback>(
994 "AsyncSetIconForPage::mCallback", aCallback, false)),
995 mIcon(aIcon),
996 mPage(aPage) {}
997
998NS_IMETHODIMPnsresult
999AsyncSetIconForPage::Run() {
1000 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1001 MOZ_ASSERT(mIcon.payloads.Length(), "The icon should have valid data")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mIcon.payloads.Length())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mIcon.payloads.Length()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("mIcon.payloads.Length()"
" (" "The icon should have valid data" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIcon.payloads.Length()"
") (" "The icon should have valid data" ")"); do { *((volatile
int*)__null) = 1001; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1002 MOZ_ASSERT(mPage.spec.Length(), "The page should have spec")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPage.spec.Length())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPage.spec.Length()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("mPage.spec.Length()"
" (" "The page should have spec" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1002); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.spec.Length()"
") (" "The page should have spec" ")"); do { *((volatile int
*)__null) = 1002; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1003 MOZ_ASSERT(mPage.guid.IsEmpty(), "The page should not have guid")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPage.guid.IsEmpty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPage.guid.IsEmpty()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mPage.guid.IsEmpty()"
" (" "The page should not have guid" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1003); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.guid.IsEmpty()"
") (" "The page should not have guid" ")"); do { *((volatile
int*)__null) = 1003; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1004
1005 nsresult rv = NS_OK;
1006 auto guard = MakeScopeExit([&]() {
1007 if (mCallback) {
1008 NS_DispatchToMainThread(
1009 NS_NewRunnableFunction("AsyncSetIconForPage::Callback",
1010 [rv, callback = std::move(mCallback)]() {
1011 (void)callback->Complete(rv);
1012 }));
1013 }
1014 });
1015
1016 // Fetch the page data.
1017 RefPtr<Database> DB = Database::GetDatabase();
1018 if (MOZ_UNLIKELY(!DB)(__builtin_expect(!!(!DB), 0))) {
1019 return (rv = NS_ERROR_UNEXPECTED);
1020 }
1021 rv = FetchPageInfo(DB, mPage);
1022 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/places/FaviconHelpers.cpp"
, 1022); return rv; } } while (false)
;
1023
1024 nsMainThreadPtrHandle<nsIFaviconDataCallback> nullCallback;
1025 AsyncAssociateIconToPage event(mIcon, mPage, nullCallback);
1026 return (rv = event.Run());
1027}
1028
1029////////////////////////////////////////////////////////////////////////////////
1030//// AsyncGetFaviconURLForPage
1031
1032AsyncGetFaviconURLForPage::AsyncGetFaviconURLForPage(
1033 const nsACString& aPageSpec, const nsACString& aPageHost,
1034 uint16_t aPreferredWidth, nsIFaviconDataCallback* aCallback)
1035 : Runnable("places::AsyncGetFaviconURLForPage"),
1036 mPreferredWidth(aPreferredWidth == 0 ? UINT16_MAX(65535) : aPreferredWidth),
1037 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
1038 "AsyncGetFaviconURLForPage::mCallback", aCallback)) {
1039 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1039); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1039; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1040 mPageSpec.Assign(aPageSpec);
1041 mPageHost.Assign(aPageHost);
1042}
1043
1044NS_IMETHODIMPnsresult
1045AsyncGetFaviconURLForPage::Run() {
1046 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1047
1048 RefPtr<Database> DB = Database::GetDatabase();
1049 NS_ENSURE_STATE(DB)do { if ((__builtin_expect(!!(!(DB)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "DB" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1049); return NS_ERROR_UNEXPECTED; } } while (false)
;
1050 IconData iconData;
1051 nsresult rv =
1052 FetchIconPerSpec(DB, mPageSpec, mPageHost, iconData, mPreferredWidth);
1053 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/places/FaviconHelpers.cpp"
, 1053); return rv; } } while (false)
;
1054
1055 // Now notify our callback of the icon spec we retrieved, even if empty.
1056 PageData pageData;
1057 pageData.spec.Assign(mPageSpec);
1058
1059 nsCOMPtr<nsIRunnable> event =
1060 new NotifyIconObservers(iconData, pageData, mCallback);
1061 rv = NS_DispatchToMainThread(event);
1062 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/places/FaviconHelpers.cpp"
, 1062); return rv; } } while (false)
;
1063
1064 return NS_OK;
1065}
1066
1067////////////////////////////////////////////////////////////////////////////////
1068//// AsyncGetFaviconDataForPage
1069
1070AsyncGetFaviconDataForPage::AsyncGetFaviconDataForPage(
1071 const nsACString& aPageSpec, const nsACString& aPageHost,
1072 uint16_t aPreferredWidth, nsIFaviconDataCallback* aCallback)
1073 : Runnable("places::AsyncGetFaviconDataForPage"),
1074 mPreferredWidth(aPreferredWidth == 0 ? UINT16_MAX(65535) : aPreferredWidth),
1075 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
1076 "AsyncGetFaviconDataForPage::mCallback", aCallback)) {
1077 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1077); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1077; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1078 mPageSpec.Assign(aPageSpec);
1079 mPageHost.Assign(aPageHost);
1080}
1081
1082NS_IMETHODIMPnsresult
1083AsyncGetFaviconDataForPage::Run() {
1084 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1084); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1084; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1085
1086 RefPtr<Database> DB = Database::GetDatabase();
1087 NS_ENSURE_STATE(DB)do { if ((__builtin_expect(!!(!(DB)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "DB" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1087); return NS_ERROR_UNEXPECTED; } } while (false)
;
1088 IconData iconData;
1089 nsresult rv =
1090 FetchIconPerSpec(DB, mPageSpec, mPageHost, iconData, mPreferredWidth);
1091 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/places/FaviconHelpers.cpp"
, 1091); return rv; } } while (false)
;
1092
1093 if (!iconData.spec.IsEmpty()) {
1094 rv = FetchIconInfo(DB, mPreferredWidth, iconData);
1095 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1096 iconData.spec.Truncate();
1097 }
1098 }
1099
1100 PageData pageData;
1101 pageData.spec.Assign(mPageSpec);
1102
1103 nsCOMPtr<nsIRunnable> event =
1104 new NotifyIconObservers(iconData, pageData, mCallback);
1105 rv = NS_DispatchToMainThread(event);
1106 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/places/FaviconHelpers.cpp"
, 1106); return rv; } } while (false)
;
1107 return NS_OK;
1108}
1109
1110////////////////////////////////////////////////////////////////////////////////
1111//// NotifyIconObservers
1112
1113NotifyIconObservers::NotifyIconObservers(
1114 const IconData& aIcon, const PageData& aPage,
1115 const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback)
1116 : Runnable("places::NotifyIconObservers"),
1117 mCallback(aCallback),
1118 mIcon(aIcon),
1119 mPage(aPage) {}
1120
1121// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is marked
1122// MOZ_CAN_RUN_SCRIPT. See bug 1535398.
1123MOZ_CAN_RUN_SCRIPT_BOUNDARY
1124NS_IMETHODIMPnsresult
1125NotifyIconObservers::Run() {
1126 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1126); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1126; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1127
1128 nsCOMPtr<nsIURI> iconURI;
1129 if (!mIcon.spec.IsEmpty()) {
1130 if (!NS_WARN_IF(NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(NS_NewURI
(getter_AddRefs(iconURI), mIcon.spec))), 0))), "NS_FAILED(NS_NewURI(getter_AddRefs(iconURI), mIcon.spec))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1131)
1131 NS_FAILED(NS_NewURI(getter_AddRefs(iconURI), mIcon.spec)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(NS_NewURI
(getter_AddRefs(iconURI), mIcon.spec))), 0))), "NS_FAILED(NS_NewURI(getter_AddRefs(iconURI), mIcon.spec))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1131)
) {
1132 // Notify observers only if something changed.
1133 if (mIcon.status & ICON_STATUS_SAVED1 << 1 ||
1134 mIcon.status & ICON_STATUS_ASSOCIATED1 << 2) {
1135 nsCOMPtr<nsIURI> pageURI;
1136 if (!NS_WARN_IF(NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(NS_NewURI
(getter_AddRefs(pageURI), mPage.spec))), 0))), "NS_FAILED(NS_NewURI(getter_AddRefs(pageURI), mPage.spec))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1137)
1137 NS_FAILED(NS_NewURI(getter_AddRefs(pageURI), mPage.spec)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(NS_NewURI
(getter_AddRefs(pageURI), mPage.spec))), 0))), "NS_FAILED(NS_NewURI(getter_AddRefs(pageURI), mPage.spec))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1137)
) {
1138 // Invalide page-icon image cache, since the icon is about to change.
1139 nsFaviconService* favicons = nsFaviconService::GetFaviconService();
1140 MOZ_ASSERT(favicons)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(favicons)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(favicons))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("favicons", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1140); AnnotateMozCrashReason("MOZ_ASSERT" "(" "favicons" ")"
); do { *((volatile int*)__null) = 1140; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1141 if (favicons) {
1142 nsCString pageIconSpec("page-icon:");
1143 pageIconSpec.Append(mPage.spec);
1144 nsCOMPtr<nsIURI> pageIconURI;
1145 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(NS_NewURI(getter_AddRefs
(pageIconURI), pageIconSpec))), 1)))
1146 NS_NewURI(getter_AddRefs(pageIconURI), pageIconSpec))((bool)(__builtin_expect(!!(!NS_FAILED_impl(NS_NewURI(getter_AddRefs
(pageIconURI), pageIconSpec))), 1)))
) {
1147 favicons->ClearImageCache(pageIconURI);
1148 }
1149 }
1150
1151 // Notify about the favicon change.
1152 dom::Sequence<OwningNonNull<dom::PlacesEvent>> events;
1153 RefPtr<dom::PlacesFavicon> faviconEvent = new dom::PlacesFavicon();
1154 AppendUTF8toUTF16(mPage.spec, faviconEvent->mUrl);
1155 AppendUTF8toUTF16(mIcon.spec, faviconEvent->mFaviconUrl);
1156 faviconEvent->mPageGuid.Assign(mPage.guid);
1157 bool success =
1158 !!events.AppendElement(faviconEvent.forget(), fallible);
1159 MOZ_RELEASE_ASSERT(success)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(success)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(success))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("success", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1159); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "success"
")"); do { *((volatile int*)__null) = 1159; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1160 dom::PlacesObservers::NotifyListeners(events);
1161 }
1162 }
1163 }
1164 }
1165
1166 if (!mCallback) {
1167 return NS_OK;
1168 }
1169
1170 if (mIcon.payloads.Length() > 0) {
1171 IconPayload& payload = mIcon.payloads[0];
1172 return mCallback->OnComplete(iconURI, payload.data.Length(),
1173 TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
, payload.mimeType,
1174 payload.width);
1175 }
1176 return mCallback->OnComplete(iconURI, 0, TO_INTBUFFER(EmptyCString())reinterpret_cast<uint8_t*>(const_cast<char*>(EmptyCString
().get()))
, ""_ns,
1177 0);
1178}
1179
1180////////////////////////////////////////////////////////////////////////////////
1181//// AsyncCopyFavicons
1182
1183AsyncCopyFavicons::AsyncCopyFavicons(PageData& aFromPage, PageData& aToPage,
1184 nsIFaviconDataCallback* aCallback)
1185 : Runnable("places::AsyncCopyFavicons"),
1186 mFromPage(aFromPage),
1187 mToPage(aToPage),
1188 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
1189 "AsyncCopyFavicons::mCallback", aCallback)) {
1190 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1190); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1190; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1191}
1192
1193NS_IMETHODIMPnsresult
1194AsyncCopyFavicons::Run() {
1195 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()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1195); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1195; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1196
1197 IconData icon;
1198
1199 // Ensure we'll callback and dispatch notifications to the main-thread.
1200 auto cleanup = MakeScopeExit([&]() {
1201 // If we bailed out early, just return a null icon uri, since we didn't
1202 // copy anything.
1203 if (!(icon.status & ICON_STATUS_ASSOCIATED1 << 2)) {
1204 icon.spec.Truncate();
1205 }
1206 nsCOMPtr<nsIRunnable> event =
1207 new NotifyIconObservers(icon, mToPage, mCallback);
1208 NS_DispatchToMainThread(event);
1209 });
1210
1211 RefPtr<Database> DB = Database::GetDatabase();
1212 NS_ENSURE_STATE(DB)do { if ((__builtin_expect(!!(!(DB)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "DB" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1212); return NS_ERROR_UNEXPECTED; } } while (false)
;
1213
1214 nsresult rv = FetchPageInfo(DB, mToPage);
1215 if (rv == NS_ERROR_NOT_AVAILABLE || !mToPage.placeId) {
1216 // We have never seen this page, or we can't add this page to history and
1217 // and it's not a bookmark. We won't add the page.
1218 return NS_OK;
1219 }
1220 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/places/FaviconHelpers.cpp"
, 1220); return rv; } } while (false)
;
1221
1222 // Get just one icon, to check whether the page has any, and to notify
1223 // later.
1224 rv = FetchIconPerSpec(DB, mFromPage.spec, ""_ns, icon, UINT16_MAX(65535));
1225 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/places/FaviconHelpers.cpp"
, 1225); return rv; } } while (false)
;
1226
1227 if (icon.spec.IsEmpty()) {
1228 // There's nothing to copy.
1229 return NS_OK;
1230 }
1231
1232 // Insert an entry in moz_pages_w_icons if needed.
1233 if (!mToPage.id) {
1234 // We need to create the page entry.
1235 nsCOMPtr<mozIStorageStatement> stmt;
1236 stmt = DB->GetStatement(
1237 "INSERT OR IGNORE INTO moz_pages_w_icons (page_url, page_url_hash) "
1238 "VALUES (:page_url, hash(:page_url)) ");
1239 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1239); return NS_ERROR_UNEXPECTED; } } while (false)
;
1240 mozStorageStatementScoper scoper(stmt);
1241 rv = URIBinder::Bind(stmt, "page_url"_ns, mToPage.spec);
1242 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/places/FaviconHelpers.cpp"
, 1242); return rv; } } while (false)
;
1243 rv = stmt->Execute();
1244 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/places/FaviconHelpers.cpp"
, 1244); return rv; } } while (false)
;
1245 // Required to to fetch the id and the guid.
1246 rv = FetchPageInfo(DB, mToPage);
1247 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/places/FaviconHelpers.cpp"
, 1247); return rv; } } while (false)
;
1248 }
1249
1250 // Create the relations.
1251 nsCOMPtr<mozIStorageStatement> stmt = DB->GetStatement(
1252 "INSERT OR IGNORE INTO moz_icons_to_pages (page_id, icon_id, expire_ms) "
1253 "SELECT :id, icon_id, expire_ms "
1254 "FROM moz_icons_to_pages "
1255 "WHERE page_id = (SELECT id FROM moz_pages_w_icons WHERE page_url_hash = "
1256 "hash(:url) AND page_url = :url) ");
1257 NS_ENSURE_STATE(stmt)do { if ((__builtin_expect(!!(!(stmt)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stmt" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 1257); return NS_ERROR_UNEXPECTED; } } while (false)
;
1258 mozStorageStatementScoper scoper(stmt);
1259 rv = stmt->BindInt64ByName("id"_ns, mToPage.id);
1260 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/places/FaviconHelpers.cpp"
, 1260); return rv; } } while (false)
;
1261 rv = URIBinder::Bind(stmt, "url"_ns, mFromPage.spec);
1262 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/places/FaviconHelpers.cpp"
, 1262); return rv; } } while (false)
;
1263 rv = stmt->Execute();
1264 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/places/FaviconHelpers.cpp"
, 1264); return rv; } } while (false)
;
1265
1266 // Setting this will make us send pageChanged notifications.
1267 // The scope exit will take care of the callback and notifications.
1268 icon.status |= ICON_STATUS_ASSOCIATED1 << 2;
1269
1270 return NS_OK;
1271}
1272
1273} // namespace places
1274} // namespace mozilla