Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp
Warning:line 424, 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-18/lib/clang/18 -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 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/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../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 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -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-05-16-034744-15991-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) "
210 "VALUES (:url, hash(fixup_url(:url)), :width, :root, :expire, :data) ");
211 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"
, 211); return NS_ERROR_UNEXPECTED; } } while (false)
;
212 // ReplaceFaviconData may replace data for an already existing icon, and in
213 // that case it won't have the page uri at hand, thus it can't tell if the
214 // icon is a root icon or not. For that reason, never overwrite a root = 1.
215 nsCOMPtr<mozIStorageStatement> updateStmt = aDB->GetStatement(
216 "UPDATE moz_icons SET width = :width, "
217 "expire_ms = :expire, "
218 "data = :data, "
219 "root = (root OR :root) "
220 "WHERE id = :id ");
221 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"
, 221); return NS_ERROR_UNEXPECTED; } } while (false)
;
222
223 for (auto& payload : aIcon.payloads) {
224 // Sanity checks.
225 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"
, 227); 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) = 227; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
226 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"
, 227); 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) = 227; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
227 "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"
, 227); 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) = 227; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
228 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"
, 230); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
") (" "SVG payloads should have max width" ")"); do { *((volatile
int*)__null) = 230; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
229 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"
, 230); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
") (" "SVG payloads should have max width" ")"); do { *((volatile
int*)__null) = 230; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
230 "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"
, 230); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!payload.mimeType.EqualsLiteral(\"image/svg+xml\") || payload.width == (65535)"
") (" "SVG payloads should have max width" ")"); do { *((volatile
int*)__null) = 230; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
231 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"
, 231); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.width > 0"
") (" "Payload should have a width" ")"); do { *((volatile int
*)__null) = 231; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
232#ifdef DEBUG1
233 // Done to ensure we fetch the id. See the MOZ_ASSERT below.
234 payload.id = 0;
235#endif
236 if (!ids.empty()) {
237 // Pop the first existing id for reuse.
238 int64_t id = ids.front();
239 ids.pop_front();
240 mozStorageStatementScoper scoper(updateStmt);
241 rv = updateStmt->BindInt64ByName("id"_ns, id);
242 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"
, 242); return rv; } } while (false)
;
243 rv = updateStmt->BindInt32ByName("width"_ns, payload.width);
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->BindInt64ByName("expire"_ns, aIcon.expiration / 1000);
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->BindInt32ByName("root"_ns, aIcon.rootIcon);
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->BindBlobByName("data"_ns, TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
,
250 payload.data.Length());
251 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"
, 251); return rv; } } while (false)
;
252 rv = updateStmt->Execute();
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 // Set the new payload id.
255 payload.id = id;
256 } else {
257 // Insert a new entry.
258 mozStorageStatementScoper scoper(insertStmt);
259 rv = URIBinder::Bind(insertStmt, "url"_ns, aIcon.spec);
260 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"
, 260); return rv; } } while (false)
;
261 rv = insertStmt->BindInt32ByName("width"_ns, payload.width);
262 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"
, 262); return rv; } } while (false)
;
263
264 rv = insertStmt->BindInt32ByName("root"_ns, aIcon.rootIcon);
265 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"
, 265); return rv; } } while (false)
;
266 rv = insertStmt->BindInt64ByName("expire"_ns, aIcon.expiration / 1000);
267 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"
, 267); return rv; } } while (false)
;
268 rv = insertStmt->BindBlobByName("data"_ns, TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
,
269 payload.data.Length());
270 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"
, 270); return rv; } } while (false)
;
271 rv = insertStmt->Execute();
272 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/places/FaviconHelpers.cpp"
, 272); return rv; } } while (false)
;
273 // Set the new payload id.
274 payload.id = nsFaviconService::sLastInsertedIconId;
275 }
276 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"
, 276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "payload.id > 0"
") (" "Payload should have an id" ")"); do { *((volatile int
*)__null) = 276; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
277 }
278
279 if (!ids.empty()) {
280 // Remove any old leftover payload.
281 nsAutoCString sql("DELETE FROM moz_icons WHERE id IN (");
282 for (int64_t id : ids) {
283 sql.AppendInt(id);
284 sql.AppendLiteral(",");
285 }
286 sql.AppendLiteral(" 0)"); // Non-existing id to match the trailing comma.
287 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(sql);
288 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"
, 288); return NS_ERROR_UNEXPECTED; } } while (false)
;
289 mozStorageStatementScoper scoper(stmt);
290 rv = stmt->Execute();
291 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"
, 291); return rv; } } while (false)
;
292 }
293
294 return NS_OK;
295}
296
297/**
298 * Fetches information on a icon url from the database.
299 *
300 * @param aDBConn
301 * Database connection to history tables.
302 * @param aPreferredWidth
303 * The preferred size to fetch.
304 * @param _icon
305 * Icon that should be fetched.
306 */
307nsresult FetchIconInfo(const RefPtr<Database>& aDB, uint16_t aPreferredWidth,
308 IconData& _icon) {
309 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"
, 309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_icon.spec.Length()"
") (" "Must have a non-empty spec!" ")"); do { *((volatile int
*)__null) = 309; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
310 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"
, 310); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 310; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
311
312 if (_icon.status & ICON_STATUS_CACHED1 << 3) {
313 // The icon data has already been set by ReplaceFaviconData.
314 return NS_OK;
315 }
316
317 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(
318 "/* do not warn (bug no: not worth having a compound index) */ "
319 "SELECT id, expire_ms, data, width, root "
320 "FROM moz_icons "
321 "WHERE fixed_icon_url_hash = hash(fixup_url(:url)) "
322 "AND icon_url = :url "
323 "ORDER BY width DESC ");
324 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"
, 324); return NS_ERROR_UNEXPECTED; } } while (false)
;
325 mozStorageStatementScoper scoper(stmt);
326
327 DebugOnly<nsresult> rv = URIBinder::Bind(stmt, "url"_ns, _icon.spec);
328 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"
, 328); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 328; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
329
330 bool hasResult = false;
331 while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult))((bool)(__builtin_expect(!!(!NS_FAILED_impl(stmt->ExecuteStep
(&hasResult))), 1)))
&& hasResult) {
332 IconPayload payload;
333 rv = stmt->GetInt64(0, &payload.id);
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 // Expiration can be nullptr.
337 bool isNull;
338 rv = stmt->GetIsNull(1, &isNull);
339 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"
, 339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 339; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
340 if (!isNull) {
341 int64_t expire_ms;
342 rv = stmt->GetInt64(1, &expire_ms);
343 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"
, 343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 343; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
344 _icon.expiration = expire_ms * 1000;
345 }
346
347 uint8_t* data;
348 uint32_t dataLen = 0;
349 rv = stmt->GetBlob(2, &dataLen, &data);
350 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"
, 350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
351 payload.data.Adopt(TO_CHARBUFFER(data)reinterpret_cast<char*>(const_cast<uint8_t*>(data
))
, dataLen);
352
353 int32_t width;
354 rv = stmt->GetInt32(3, &width);
355 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"
, 355); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 355; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
356 payload.width = width;
357 if (payload.width == UINT16_MAX(65535)) {
358 payload.mimeType.AssignLiteral(SVG_MIME_TYPE"image/svg+xml");
359 } else {
360 payload.mimeType.AssignLiteral(PNG_MIME_TYPE"image/png");
361 }
362
363 int32_t rootIcon;
364 rv = stmt->GetInt32(4, &rootIcon);
365 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"
, 365); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 365; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
366 _icon.rootIcon = rootIcon;
367
368 if (aPreferredWidth == 0 || _icon.payloads.Length() == 0) {
369 _icon.payloads.AppendElement(payload);
370 } else if (payload.width >= aPreferredWidth) {
371 // Only retain the best matching payload.
372 _icon.payloads.ReplaceElementAt(0, payload);
373 } else {
374 break;
375 }
376 }
377
378 return NS_OK;
379}
380
381nsresult FetchIconPerSpec(const RefPtr<Database>& aDB,
382 const nsACString& aPageSpec,
383 const nsACString& aPageHost, IconData& aIconData,
384 uint16_t aPreferredWidth) {
385 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"
, 385); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aPageSpec.IsEmpty()"
") (" "Page spec must not be empty." ")"); do { *((volatile int
*)__null) = 385; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
386 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"
, 386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
387
388 // This selects both associated and root domain icons, ordered by width,
389 // where an associated icon has priority over a root domain icon.
390 // Regardless, note that while this way we are far more efficient, we lost
391 // associations with root domain icons, so it's possible we'll return one
392 // for a specific size when an associated icon for that size doesn't exist.
393 nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(
394 "/* do not warn (bug no: not worth having a compound index) */ "
395 "SELECT width, icon_url, root "
396 "FROM moz_icons i "
397 "JOIN moz_icons_to_pages ON i.id = icon_id "
398 "JOIN moz_pages_w_icons p ON p.id = page_id "
399 "WHERE page_url_hash = hash(:url) AND page_url = :url "
400 "OR (:hash_idx AND page_url_hash = hash(substr(:url, 0, :hash_idx)) "
401 "AND page_url = substr(:url, 0, :hash_idx)) "
402 "UNION ALL "
403 "SELECT width, icon_url, root "
404 "FROM moz_icons i "
405 "WHERE fixed_icon_url_hash = hash(fixup_url(:host) || '/favicon.ico') "
406 "ORDER BY width DESC, root ASC");
407 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"
, 407); return NS_ERROR_UNEXPECTED; } } while (false)
;
408 mozStorageStatementScoper scoper(stmt);
409
410 nsresult rv = URIBinder::Bind(stmt, "url"_ns, aPageSpec);
411 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"
, 411); return rv; } } while (false)
;
412 rv = stmt->BindUTF8StringByName("host"_ns, aPageHost);
413 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"
, 413); return rv; } } while (false)
;
414 int32_t hashIdx = PromiseFlatCStringTPromiseFlatString<char>(aPageSpec).RFind("#");
415 rv = stmt->BindInt32ByName("hash_idx"_ns, hashIdx + 1);
416 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"
, 416); return rv; } } while (false)
;
417
418 // Return the biggest icon close to the preferred width. It may be bigger
419 // or smaller if the preferred width isn't found.
420 bool hasResult;
421 int32_t lastWidth = 0;
422 while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResult))((bool)(__builtin_expect(!!(!NS_FAILED_impl(stmt->ExecuteStep
(&hasResult))), 1)))
&& hasResult) {
423 int32_t width;
424 rv = stmt->GetInt32(0, &width);
Value stored to 'rv' is never read
425 if (lastWidth == width) {
426 // We already found an icon for this width. We always prefer the first
427 // icon found, because it's a non-root icon, per the root ASC ordering.
428 continue;
429 }
430 if (!aIconData.spec.IsEmpty() && width < aPreferredWidth) {
431 // We found the best match, or we already found a match so we don't need
432 // to fallback to the root domain icon.
433 break;
434 }
435 lastWidth = width;
436 rv = stmt->GetUTF8String(1, aIconData.spec);
437 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"
, 437); return rv; } } while (false)
;
438 }
439
440 return NS_OK;
441}
442
443/**
444 * Tries to compute the expiration time for a icon from the channel.
445 *
446 * @param aChannel
447 * The network channel used to fetch the icon.
448 * @return a valid expiration value for the fetched icon.
449 */
450PRTime GetExpirationTimeFromChannel(nsIChannel* aChannel) {
451 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"
, 451); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 451; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
452
453 // Attempt to get an expiration time from the cache. If this fails, we'll
454 // make one up.
455 PRTime now = PR_Now();
456 PRTime expiration = -1;
457 nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aChannel);
458 if (cachingChannel) {
459 nsCOMPtr<nsISupports> cacheToken;
460 nsresult rv = cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
461 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
462 nsCOMPtr<nsICacheEntry> cacheEntry = do_QueryInterface(cacheToken);
463 uint32_t seconds;
464 rv = cacheEntry->GetExpirationTime(&seconds);
465 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
466 // Set the expiration, but make sure we honor our cap.
467 expiration = now + std::min((PRTime)seconds * PR_USEC_PER_SEC1000000L,
468 MAX_FAVICON_EXPIRATION((PRTime)7 * 24 * 60 * 60 * 1000000L));
469 }
470 }
471 }
472 // If we did not obtain a time from the cache, use the cap value.
473 return expiration < now + MIN_FAVICON_EXPIRATION((PRTime)1 * 24 * 60 * 60 * 1000000L)
474 ? now + MAX_FAVICON_EXPIRATION((PRTime)7 * 24 * 60 * 60 * 1000000L)
475 : expiration;
476}
477
478} // namespace
479
480////////////////////////////////////////////////////////////////////////////////
481//// AsyncFetchAndSetIconForPage
482
483NS_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"
, 485); 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; }
484 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"
, 485); 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; }
485 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"
, 485); 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; }
486
487AsyncFetchAndSetIconForPage::AsyncFetchAndSetIconForPage(
488 IconData& aIcon, PageData& aPage, bool aFaviconLoadPrivate,
489 nsIFaviconDataCallback* aCallback, nsIPrincipal* aLoadingPrincipal,
490 uint64_t aRequestContextID)
491 : Runnable("places::AsyncFetchAndSetIconForPage"),
492 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
493 "AsyncFetchAndSetIconForPage::mCallback", aCallback)),
494 mIcon(aIcon),
495 mPage(aPage),
496 mFaviconLoadPrivate(aFaviconLoadPrivate),
497 mLoadingPrincipal(new nsMainThreadPtrHolder<nsIPrincipal>(
498 "AsyncFetchAndSetIconForPage::mLoadingPrincipal", aLoadingPrincipal)),
499 mCanceled(false),
500 mRequestContextID(aRequestContextID) {
501 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"
, 501); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 501; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
502}
503
504NS_IMETHODIMPnsresult
505AsyncFetchAndSetIconForPage::Run() {
506 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"
, 506); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 506; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
507
508 // Try to fetch the icon from the database.
509 RefPtr<Database> DB = Database::GetDatabase();
510 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"
, 510); return NS_ERROR_UNEXPECTED; } } while (false)
;
511 nsresult rv = FetchIconInfo(DB, 0, mIcon);
512 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"
, 512); return rv; } } while (false)
;
513
514 bool isInvalidIcon = !mIcon.payloads.Length() || PR_Now() > mIcon.expiration;
515 bool fetchIconFromNetwork =
516 mIcon.fetchMode == FETCH_ALWAYS ||
517 (mIcon.fetchMode == FETCH_IF_MISSING && isInvalidIcon);
518
519 // Check if we can associate the icon to this page.
520 rv = FetchPageInfo(DB, mPage);
521 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
522 if (rv == NS_ERROR_NOT_AVAILABLE) {
523 // We have never seen this page. If we can add the page to history,
524 // we will try to do it later, otherwise just bail out.
525 if (!mPage.canAddToHistory) {
526 return NS_OK;
527 }
528 }
529 return rv;
530 }
531
532 if (!fetchIconFromNetwork) {
533 // There is already a valid icon or we don't want to fetch a new one,
534 // directly proceed with association.
535 RefPtr<AsyncAssociateIconToPage> event =
536 new AsyncAssociateIconToPage(mIcon, mPage, mCallback);
537 // We're already on the async thread.
538 return event->Run();
539 }
540
541 // Fetch the icon from the network, the request starts from the main-thread.
542 // When done this will associate the icon to the page and notify.
543 nsCOMPtr<nsIRunnable> event =
544 NewRunnableMethod("places::AsyncFetchAndSetIconForPage::FetchFromNetwork",
545 this, &AsyncFetchAndSetIconForPage::FetchFromNetwork);
546 return NS_DispatchToMainThread(event);
547}
548
549nsresult AsyncFetchAndSetIconForPage::FetchFromNetwork() {
550 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"
, 550); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 550; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
551
552 if (mCanceled) {
553 return NS_OK;
554 }
555
556 // Ensure data is cleared, since it's going to be overwritten.
557 mIcon.payloads.Clear();
558
559 IconPayload payload;
560 mIcon.payloads.AppendElement(payload);
561
562 nsCOMPtr<nsIURI> iconURI;
563 nsresult rv = NS_NewURI(getter_AddRefs(iconURI), mIcon.spec);
564 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"
, 564); return rv; } } while (false)
;
565 nsCOMPtr<nsIChannel> channel;
566 rv = NS_NewChannel(getter_AddRefs(channel), iconURI, mLoadingPrincipal,
567 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT |
568 nsILoadInfo::SEC_ALLOW_CHROME |
569 nsILoadInfo::SEC_DISALLOW_SCRIPT,
570 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON);
571
572 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"
, 572); return rv; } } while (false)
;
573 nsCOMPtr<nsIInterfaceRequestor> listenerRequestor =
574 do_QueryInterface(reinterpret_cast<nsISupports*>(this));
575 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"
, 575); return NS_ERROR_UNEXPECTED; } } while (false)
;
576 rv = channel->SetNotificationCallbacks(listenerRequestor);
577 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"
, 577); return rv; } } while (false)
;
578 nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(channel);
579 if (pbChannel) {
580 rv = pbChannel->SetPrivate(mFaviconLoadPrivate);
581 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"
, 581); return rv; } } while (false)
;
582 }
583
584 nsCOMPtr<nsISupportsPriority> priorityChannel = do_QueryInterface(channel);
585 if (priorityChannel) {
586 priorityChannel->AdjustPriority(nsISupportsPriority::PRIORITY_LOWEST);
587 }
588
589 if (StaticPrefs::network_http_tailing_enabled()) {
590 nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel);
591 if (cos) {
592 cos->AddClassFlags(nsIClassOfService::Tail |
593 nsIClassOfService::Throttleable);
594 }
595
596 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
597 if (httpChannel) {
598 Unused << httpChannel->SetRequestContextID(mRequestContextID);
599 }
600 }
601
602 rv = channel->AsyncOpen(this);
603 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
604 mRequest = channel;
605 }
606 return rv;
607}
608
609NS_IMETHODIMPnsresult
610AsyncFetchAndSetIconForPage::Cancel() {
611 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"
, 611); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 611; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
612 if (mCanceled) {
613 return NS_ERROR_UNEXPECTED;
614 }
615 mCanceled = true;
616 if (mRequest) {
617 mRequest->CancelWithReason(NS_BINDING_ABORTED,
618 "AsyncFetchAndSetIconForPage::Cancel"_ns);
619 }
620 return NS_OK;
621}
622
623NS_IMETHODIMPnsresult
624AsyncFetchAndSetIconForPage::OnStartRequest(nsIRequest* aRequest) {
625 // mRequest should already be set from ::FetchFromNetwork, but in the case of
626 // a redirect we might get a new request, and we should make sure we keep a
627 // reference to the most current request.
628 mRequest = aRequest;
629 if (mCanceled) {
630 mRequest->Cancel(NS_BINDING_ABORTED);
631 }
632 // Don't store icons responding with Cache-Control: no-store, but always
633 // allow root domain icons.
634 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
635 if (httpChannel) {
636 bool isNoStore;
637 nsAutoCString path;
638 nsCOMPtr<nsIURI> uri;
639 if (NS_SUCCEEDED(httpChannel->GetURI(getter_AddRefs(uri)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetURI
(getter_AddRefs(uri)))), 1)))
&&
640 NS_SUCCEEDED(uri->GetFilePath(path))((bool)(__builtin_expect(!!(!NS_FAILED_impl(uri->GetFilePath
(path))), 1)))
&&
641 !path.EqualsLiteral("/favicon.ico") &&
642 NS_SUCCEEDED(httpChannel->IsNoStoreResponse(&isNoStore))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->IsNoStoreResponse
(&isNoStore))), 1)))
&& isNoStore) {
643 // Abandon the network fetch.
644 mRequest->CancelWithReason(
645 NS_BINDING_ABORTED, "AsyncFetchAndSetIconForPage::OnStartRequest"_ns);
646 }
647 }
648 return NS_OK;
649}
650
651NS_IMETHODIMPnsresult
652AsyncFetchAndSetIconForPage::OnDataAvailable(nsIRequest* aRequest,
653 nsIInputStream* aInputStream,
654 uint64_t aOffset,
655 uint32_t aCount) {
656 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"
, 656); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIcon.payloads.Length() == 1"
")"); do { *((volatile int*)__null) = 656; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
657 // Limit downloads to 500KB.
658 const size_t kMaxDownloadSize = 500 * 1024;
659 if (mIcon.payloads[0].data.Length() + aCount > kMaxDownloadSize) {
660 mIcon.payloads.Clear();
661 return NS_ERROR_FILE_TOO_BIG;
662 }
663
664 nsAutoCString buffer;
665 nsresult rv = NS_ConsumeStream(aInputStream, aCount, buffer);
666 if (rv != NS_BASE_STREAM_WOULD_BLOCK && NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
667 return rv;
668 }
669
670 if (!mIcon.payloads[0].data.Append(buffer, fallible)) {
671 mIcon.payloads.Clear();
672 return NS_ERROR_OUT_OF_MEMORY;
673 }
674
675 return NS_OK;
676}
677
678NS_IMETHODIMPnsresult
679AsyncFetchAndSetIconForPage::GetInterface(const nsIID& uuid, void** aResult) {
680 return QueryInterface(uuid, aResult);
681}
682
683NS_IMETHODIMPnsresult
684AsyncFetchAndSetIconForPage::AsyncOnChannelRedirect(
685 nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
686 nsIAsyncVerifyRedirectCallback* cb) {
687 // If we've been canceled, stop the redirect with NS_BINDING_ABORTED, and
688 // handle the cancel on the original channel.
689 (void)cb->OnRedirectVerifyCallback(mCanceled ? NS_BINDING_ABORTED : NS_OK);
690 return NS_OK;
691}
692
693NS_IMETHODIMPnsresult
694AsyncFetchAndSetIconForPage::OnStopRequest(nsIRequest* aRequest,
695 nsresult aStatusCode) {
696 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"
, 696); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 696; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
697
698 // Don't need to track this anymore.
699 mRequest = nullptr;
700 if (mCanceled) {
701 return NS_OK;
702 }
703
704 nsFaviconService* favicons = nsFaviconService::GetFaviconService();
705 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"
, 705); return NS_ERROR_UNEXPECTED; } } while (false)
;
706
707 nsresult rv;
708
709 // If fetching the icon failed, bail out.
710 if (NS_FAILED(aStatusCode)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatusCode)), 0))
)
|| mIcon.payloads.Length() == 0) {
711 return NS_OK;
712 }
713
714 nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
715 // aRequest should always QI to nsIChannel.
716 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"
, 716); AnnotateMozCrashReason("MOZ_ASSERT" "(" "channel" ")"
); do { *((volatile int*)__null) = 716; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
717
718 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"
, 718); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIcon.payloads.Length() == 1"
")"); do { *((volatile int*)__null) = 718; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
719 IconPayload& payload = mIcon.payloads[0];
720
721 nsAutoCString contentType;
722 channel->GetContentType(contentType);
723 // Bug 366324 - We don't want to sniff for SVG, so rely on server-specified
724 // type.
725 if (contentType.EqualsLiteral(SVG_MIME_TYPE"image/svg+xml")) {
726 payload.mimeType.AssignLiteral(SVG_MIME_TYPE"image/svg+xml");
727 payload.width = UINT16_MAX(65535);
728 } else {
729 NS_SniffContent(NS_DATA_SNIFFER_CATEGORY"content-sniffing-services", aRequest,
730 TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
, payload.data.Length(),
731 payload.mimeType);
732 }
733
734 // If the icon does not have a valid MIME type, bail out.
735 if (payload.mimeType.IsEmpty()) {
736 return NS_OK;
737 }
738
739 mIcon.expiration = GetExpirationTimeFromChannel(channel);
740
741 // Telemetry probes to measure the favicon file sizes for each different file
742 // type. This allow us to measure common file sizes while also observing each
743 // type popularity.
744 if (payload.mimeType.EqualsLiteral(PNG_MIME_TYPE"image/png")) {
745 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_PNG_SIZES,
746 payload.data.Length());
747 } else if (payload.mimeType.EqualsLiteral("image/x-icon") ||
748 payload.mimeType.EqualsLiteral("image/vnd.microsoft.icon")) {
749 Telemetry::Accumulate(mozilla::Telemetry::PLACES_FAVICON_ICO_SIZES,
750 payload.data.Length());
751 } else if (payload.mimeType.EqualsLiteral("image/jpeg") ||
752 payload.mimeType.EqualsLiteral("image/pjpeg")) {
753 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_JPEG_SIZES,
754 payload.data.Length());
755 } else if (payload.mimeType.EqualsLiteral("image/gif")) {
756 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_GIF_SIZES,
757 payload.data.Length());
758 } else if (payload.mimeType.EqualsLiteral("image/bmp") ||
759 payload.mimeType.EqualsLiteral("image/x-windows-bmp")) {
760 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_BMP_SIZES,
761 payload.data.Length());
762 } else if (payload.mimeType.EqualsLiteral(SVG_MIME_TYPE"image/svg+xml")) {
763 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_SVG_SIZES,
764 payload.data.Length());
765 } else {
766 Telemetry::Accumulate(Telemetry::PLACES_FAVICON_OTHER_SIZES,
767 payload.data.Length());
768 }
769
770 rv = favicons->OptimizeIconSizes(mIcon);
771 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"
, 771); return rv; } } while (false)
;
772
773 // If there's not valid payload, don't store the icon into to the database.
774 if (mIcon.payloads.Length() == 0) {
775 return NS_OK;
776 }
777
778 mIcon.status = ICON_STATUS_CHANGED1 << 0;
779
780 RefPtr<Database> DB = Database::GetDatabase();
781 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"
, 781); return NS_ERROR_UNEXPECTED; } } while (false)
;
782 RefPtr<AsyncAssociateIconToPage> event =
783 new AsyncAssociateIconToPage(mIcon, mPage, mCallback);
784 DB->DispatchToAsyncThread(event);
785
786 return NS_OK;
787}
788
789////////////////////////////////////////////////////////////////////////////////
790//// AsyncAssociateIconToPage
791
792AsyncAssociateIconToPage::AsyncAssociateIconToPage(
793 const IconData& aIcon, const PageData& aPage,
794 const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback)
795 : Runnable("places::AsyncAssociateIconToPage"),
796 mCallback(aCallback),
797 mIcon(aIcon),
798 mPage(aPage) {
799 // May be created in both threads.
800}
801
802NS_IMETHODIMPnsresult
803AsyncAssociateIconToPage::Run() {
804 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"
, 804); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 804; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
805 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"
, 806); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPage.guid.IsEmpty()"
") (" "Page info should have been fetched already" ")"); do {
*((volatile int*)__null) = 806; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
806 "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"
, 806); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPage.guid.IsEmpty()"
") (" "Page info should have been fetched already" ")"); do {
*((volatile int*)__null) = 806; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
807 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"
, 808); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty()"
") (" "The page should be addable to history or a bookmark" ")"
); do { *((volatile int*)__null) = 808; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
808 "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"
, 808); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.canAddToHistory || !mPage.bookmarkedSpec.IsEmpty()"
") (" "The page should be addable to history or a bookmark" ")"
); do { *((volatile int*)__null) = 808; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
809
810 bool shouldUpdateIcon = mIcon.status & ICON_STATUS_CHANGED1 << 0;
811 if (!shouldUpdateIcon) {
812 for (const auto& payload : mIcon.payloads) {
813 // If the entry is missing from the database, we should add it.
814 if (payload.id == 0) {
815 shouldUpdateIcon = true;
816 break;
817 }
818 }
819 }
820
821 RefPtr<Database> DB = Database::GetDatabase();
822 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"
, 822); return NS_ERROR_UNEXPECTED; } } while (false)
;
823
824 mozStorageTransaction transaction(
825 DB->MainConn(), false, mozIStorageConnection::TRANSACTION_IMMEDIATE);
826
827 // XXX Handle the error, bug 1696133.
828 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"
, 828)
;
829
830 nsresult rv;
831 if (shouldUpdateIcon) {
832 rv = SetIconInfo(DB, mIcon);
833 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
834 (void)transaction.Commit();
835 return rv;
836 }
837
838 mIcon.status = (mIcon.status & ~(ICON_STATUS_CACHED1 << 3)) | ICON_STATUS_SAVED1 << 1;
839 }
840
841 // If the page does not have an id, don't try to insert a new one, cause we
842 // don't know where the page comes from. Not doing so we may end adding
843 // a page that otherwise we'd explicitly ignore, like a POST or an error page.
844 if (mPage.placeId == 0) {
845 rv = transaction.Commit();
846 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"
, 846); return rv; } } while (false)
;
847 return NS_OK;
848 }
849
850 // Expire old favicons to keep up with website changes. Associated icons must
851 // be expired also when storing a root favicon, because a page may change to
852 // only have a root favicon.
853 // Note that here we could also be in the process of adding further payloads
854 // to a page, and we don't want to expire just added payloads. For this
855 // reason we only remove expired payloads.
856 // Oprhan icons are not removed at this time because it'd be expensive. The
857 // privacy implications are limited, since history removal methods also expire
858 // orphan icons.
859 if (mPage.id > 0) {
860 nsCOMPtr<mozIStorageStatement> stmt;
861 stmt = DB->GetStatement(
862 "DELETE FROM moz_icons_to_pages "
863 "WHERE page_id = :page_id "
864 "AND expire_ms < strftime('%s','now','localtime','utc') * 1000 ");
865 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"
, 865); return NS_ERROR_UNEXPECTED; } } while (false)
;
866 mozStorageStatementScoper scoper(stmt);
867 rv = stmt->BindInt64ByName("page_id"_ns, mPage.id);
868 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"
, 868); return rv; } } while (false)
;
869 rv = stmt->Execute();
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 }
872
873 // Don't associate pages to root domain icons, since those will be returned
874 // regardless. This saves a lot of work and database space since we don't
875 // need to store urls and relations.
876 // Though, this is possible only if both the page and the icon have the same
877 // host, otherwise we couldn't relate them.
878 if (!mIcon.rootIcon || !mIcon.host.Equals(mPage.host)) {
879 // The page may have associated payloads already, and those could have to be
880 // expired. For example at a certain point a page could decide to stop
881 // serving its usual 16px and 32px pngs, and use an svg instead. On the
882 // other side, we could also be in the process of adding more payloads to
883 // this page, and we should not expire the payloads we just added. For this,
884 // we use the expiration field as an indicator and remove relations based on
885 // it being elapsed. We don't remove orphan icons at this time since it
886 // would have a cost. The privacy hit is limited since history removal
887 // methods already expire orphan icons.
888 if (mPage.id == 0) {
889 // We need to create the page entry.
890 nsCOMPtr<mozIStorageStatement> stmt;
891 stmt = DB->GetStatement(
892 "INSERT OR IGNORE INTO moz_pages_w_icons (page_url, page_url_hash) "
893 "VALUES (:page_url, hash(:page_url)) ");
894 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"
, 894); return NS_ERROR_UNEXPECTED; } } while (false)
;
895 mozStorageStatementScoper scoper(stmt);
896 rv = URIBinder::Bind(stmt, "page_url"_ns, mPage.spec);
897 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"
, 897); return rv; } } while (false)
;
898 rv = stmt->Execute();
899 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"
, 899); return rv; } } while (false)
;
900 }
901
902 // Then we can create the relations.
903 nsCOMPtr<mozIStorageStatement> stmt;
904 stmt = DB->GetStatement(
905 "INSERT INTO moz_icons_to_pages (page_id, icon_id, expire_ms) "
906 "VALUES ((SELECT id from moz_pages_w_icons WHERE page_url_hash = "
907 "hash(:page_url) AND page_url = :page_url), "
908 ":icon_id, :expire) "
909 "ON CONFLICT(page_id, icon_id) DO "
910 "UPDATE SET expire_ms = :expire ");
911 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"
, 911); return NS_ERROR_UNEXPECTED; } } while (false)
;
912
913 // For some reason using BindingParamsArray here fails execution, so we must
914 // execute the statements one by one.
915 // In the future we may want to investigate the reasons, sounds like related
916 // to contraints.
917 for (const auto& payload : mIcon.payloads) {
918 mozStorageStatementScoper scoper(stmt);
919 nsCOMPtr<mozIStorageBindingParams> params;
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->BindInt64ByName("icon_id"_ns, payload.id);
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 rv = stmt->BindInt64ByName("expire"_ns, mIcon.expiration / 1000);
925 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"
, 925); return rv; } } while (false)
;
926 rv = stmt->Execute();
927 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"
, 927); return rv; } } while (false)
;
928 }
929 }
930
931 mIcon.status |= ICON_STATUS_ASSOCIATED1 << 2;
932
933 rv = transaction.Commit();
934 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"
, 934); return rv; } } while (false)
;
935
936 // Finally, dispatch an event to the main thread to notify observers.
937 nsCOMPtr<nsIRunnable> event =
938 new NotifyIconObservers(mIcon, mPage, mCallback);
939 rv = NS_DispatchToMainThread(event);
940 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"
, 940); return rv; } } while (false)
;
941
942 // If there is a bookmarked page that redirects to this one, try to update its
943 // icon as well.
944 if (!mPage.bookmarkedSpec.IsEmpty() &&
945 !mPage.bookmarkedSpec.Equals(mPage.spec)) {
946 // Create a new page struct to avoid polluting it with old data.
947 PageData bookmarkedPage;
948 bookmarkedPage.spec = mPage.bookmarkedSpec;
949 RefPtr<Database> DB = Database::GetDatabase();
950 if (DB && NS_SUCCEEDED(FetchPageInfo(DB, bookmarkedPage))((bool)(__builtin_expect(!!(!NS_FAILED_impl(FetchPageInfo(DB,
bookmarkedPage))), 1)))
) {
951 // This will be silent, so be sure to not pass in the current callback.
952 nsMainThreadPtrHandle<nsIFaviconDataCallback> nullCallback;
953 RefPtr<AsyncAssociateIconToPage> event =
954 new AsyncAssociateIconToPage(mIcon, bookmarkedPage, nullCallback);
955 Unused << event->Run();
956 }
957 }
958
959 return NS_OK;
960}
961
962////////////////////////////////////////////////////////////////////////////////
963//// AsyncSetIconForPage
964
965AsyncSetIconForPage::AsyncSetIconForPage(const IconData& aIcon,
966 const PageData& aPage,
967 PlacesCompletionCallback* aCallback)
968 : Runnable("places::AsyncSetIconForPage"),
969 mCallback(new nsMainThreadPtrHolder<PlacesCompletionCallback>(
970 "AsyncSetIconForPage::mCallback", aCallback, false)),
971 mIcon(aIcon),
972 mPage(aPage) {}
973
974NS_IMETHODIMPnsresult
975AsyncSetIconForPage::Run() {
976 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"
, 976); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 976; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
977 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"
, 977); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mIcon.payloads.Length()"
") (" "The icon should have valid data" ")"); do { *((volatile
int*)__null) = 977; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
978 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"
, 978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.spec.Length()"
") (" "The page should have spec" ")"); do { *((volatile int
*)__null) = 978; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
979 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"
, 979); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPage.guid.IsEmpty()"
") (" "The page should not have guid" ")"); do { *((volatile
int*)__null) = 979; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
980
981 nsresult rv = NS_OK;
982 auto guard = MakeScopeExit([&]() {
983 if (mCallback) {
984 NS_DispatchToMainThread(
985 NS_NewRunnableFunction("AsyncSetIconForPage::Callback",
986 [rv, callback = std::move(mCallback)]() {
987 (void)callback->Complete(rv);
988 }));
989 }
990 });
991
992 // Fetch the page data.
993 RefPtr<Database> DB = Database::GetDatabase();
994 if (MOZ_UNLIKELY(!DB)(__builtin_expect(!!(!DB), 0))) {
995 return (rv = NS_ERROR_UNEXPECTED);
996 }
997 rv = FetchPageInfo(DB, mPage);
998 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"
, 998); return rv; } } while (false)
;
999
1000 nsMainThreadPtrHandle<nsIFaviconDataCallback> nullCallback;
1001 AsyncAssociateIconToPage event(mIcon, mPage, nullCallback);
1002 return (rv = event.Run());
1003}
1004
1005////////////////////////////////////////////////////////////////////////////////
1006//// AsyncGetFaviconURLForPage
1007
1008AsyncGetFaviconURLForPage::AsyncGetFaviconURLForPage(
1009 const nsACString& aPageSpec, const nsACString& aPageHost,
1010 uint16_t aPreferredWidth, nsIFaviconDataCallback* aCallback)
1011 : Runnable("places::AsyncGetFaviconURLForPage"),
1012 mPreferredWidth(aPreferredWidth == 0 ? UINT16_MAX(65535) : aPreferredWidth),
1013 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
1014 "AsyncGetFaviconURLForPage::mCallback", aCallback)) {
1015 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"
, 1015); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1015; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1016 mPageSpec.Assign(aPageSpec);
1017 mPageHost.Assign(aPageHost);
1018}
1019
1020NS_IMETHODIMPnsresult
1021AsyncGetFaviconURLForPage::Run() {
1022 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"
, 1022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1022; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1023
1024 RefPtr<Database> DB = Database::GetDatabase();
1025 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"
, 1025); return NS_ERROR_UNEXPECTED; } } while (false)
;
1026 IconData iconData;
1027 nsresult rv =
1028 FetchIconPerSpec(DB, mPageSpec, mPageHost, iconData, mPreferredWidth);
1029 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"
, 1029); return rv; } } while (false)
;
1030
1031 // Now notify our callback of the icon spec we retrieved, even if empty.
1032 PageData pageData;
1033 pageData.spec.Assign(mPageSpec);
1034
1035 nsCOMPtr<nsIRunnable> event =
1036 new NotifyIconObservers(iconData, pageData, mCallback);
1037 rv = NS_DispatchToMainThread(event);
1038 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"
, 1038); return rv; } } while (false)
;
1039
1040 return NS_OK;
1041}
1042
1043////////////////////////////////////////////////////////////////////////////////
1044//// AsyncGetFaviconDataForPage
1045
1046AsyncGetFaviconDataForPage::AsyncGetFaviconDataForPage(
1047 const nsACString& aPageSpec, const nsACString& aPageHost,
1048 uint16_t aPreferredWidth, nsIFaviconDataCallback* aCallback)
1049 : Runnable("places::AsyncGetFaviconDataForPage"),
1050 mPreferredWidth(aPreferredWidth == 0 ? UINT16_MAX(65535) : aPreferredWidth),
1051 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
1052 "AsyncGetFaviconDataForPage::mCallback", aCallback)) {
1053 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"
, 1053); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1053; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1054 mPageSpec.Assign(aPageSpec);
1055 mPageHost.Assign(aPageHost);
1056}
1057
1058NS_IMETHODIMPnsresult
1059AsyncGetFaviconDataForPage::Run() {
1060 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"
, 1060); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1060; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1061
1062 RefPtr<Database> DB = Database::GetDatabase();
1063 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"
, 1063); return NS_ERROR_UNEXPECTED; } } while (false)
;
1064 IconData iconData;
1065 nsresult rv =
1066 FetchIconPerSpec(DB, mPageSpec, mPageHost, iconData, mPreferredWidth);
1067 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"
, 1067); return rv; } } while (false)
;
1068
1069 if (!iconData.spec.IsEmpty()) {
1070 rv = FetchIconInfo(DB, mPreferredWidth, iconData);
1071 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1072 iconData.spec.Truncate();
1073 }
1074 }
1075
1076 PageData pageData;
1077 pageData.spec.Assign(mPageSpec);
1078
1079 nsCOMPtr<nsIRunnable> event =
1080 new NotifyIconObservers(iconData, pageData, mCallback);
1081 rv = NS_DispatchToMainThread(event);
1082 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"
, 1082); return rv; } } while (false)
;
1083 return NS_OK;
1084}
1085
1086////////////////////////////////////////////////////////////////////////////////
1087//// NotifyIconObservers
1088
1089NotifyIconObservers::NotifyIconObservers(
1090 const IconData& aIcon, const PageData& aPage,
1091 const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback)
1092 : Runnable("places::NotifyIconObservers"),
1093 mCallback(aCallback),
1094 mIcon(aIcon),
1095 mPage(aPage) {}
1096
1097// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is marked
1098// MOZ_CAN_RUN_SCRIPT. See bug 1535398.
1099MOZ_CAN_RUN_SCRIPT_BOUNDARY
1100NS_IMETHODIMPnsresult
1101NotifyIconObservers::Run() {
1102 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"
, 1102); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1102; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1103
1104 nsCOMPtr<nsIURI> iconURI;
1105 if (!mIcon.spec.IsEmpty()) {
1106 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"
, 1107)
1107 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"
, 1107)
) {
1108 // Notify observers only if something changed.
1109 if (mIcon.status & ICON_STATUS_SAVED1 << 1 ||
1110 mIcon.status & ICON_STATUS_ASSOCIATED1 << 2) {
1111 nsCOMPtr<nsIURI> pageURI;
1112 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"
, 1113)
1113 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"
, 1113)
) {
1114 // Invalide page-icon image cache, since the icon is about to change.
1115 nsFaviconService* favicons = nsFaviconService::GetFaviconService();
1116 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"
, 1116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "favicons" ")"
); do { *((volatile int*)__null) = 1116; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1117 if (favicons) {
1118 nsCString pageIconSpec("page-icon:");
1119 pageIconSpec.Append(mPage.spec);
1120 nsCOMPtr<nsIURI> pageIconURI;
1121 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(NS_NewURI(getter_AddRefs
(pageIconURI), pageIconSpec))), 1)))
1122 NS_NewURI(getter_AddRefs(pageIconURI), pageIconSpec))((bool)(__builtin_expect(!!(!NS_FAILED_impl(NS_NewURI(getter_AddRefs
(pageIconURI), pageIconSpec))), 1)))
) {
1123 favicons->ClearImageCache(pageIconURI);
1124 }
1125 }
1126
1127 // Notify about the favicon change.
1128 dom::Sequence<OwningNonNull<dom::PlacesEvent>> events;
1129 RefPtr<dom::PlacesFavicon> faviconEvent = new dom::PlacesFavicon();
1130 AppendUTF8toUTF16(mPage.spec, faviconEvent->mUrl);
1131 AppendUTF8toUTF16(mIcon.spec, faviconEvent->mFaviconUrl);
1132 faviconEvent->mPageGuid.Assign(mPage.guid);
1133 bool success =
1134 !!events.AppendElement(faviconEvent.forget(), fallible);
1135 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"
, 1135); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "success"
")"); do { *((volatile int*)__null) = 1135; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1136 dom::PlacesObservers::NotifyListeners(events);
1137 }
1138 }
1139 }
1140 }
1141
1142 if (!mCallback) {
1143 return NS_OK;
1144 }
1145
1146 if (mIcon.payloads.Length() > 0) {
1147 IconPayload& payload = mIcon.payloads[0];
1148 return mCallback->OnComplete(iconURI, payload.data.Length(),
1149 TO_INTBUFFER(payload.data)reinterpret_cast<uint8_t*>(const_cast<char*>(payload
.data.get()))
, payload.mimeType,
1150 payload.width);
1151 }
1152 return mCallback->OnComplete(iconURI, 0, TO_INTBUFFER(EmptyCString())reinterpret_cast<uint8_t*>(const_cast<char*>(EmptyCString
().get()))
, ""_ns,
1153 0);
1154}
1155
1156////////////////////////////////////////////////////////////////////////////////
1157//// AsyncCopyFavicons
1158
1159AsyncCopyFavicons::AsyncCopyFavicons(PageData& aFromPage, PageData& aToPage,
1160 nsIFaviconDataCallback* aCallback)
1161 : Runnable("places::AsyncCopyFavicons"),
1162 mFromPage(aFromPage),
1163 mToPage(aToPage),
1164 mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(
1165 "AsyncCopyFavicons::mCallback", aCallback)) {
1166 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"
, 1166); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1166; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1167}
1168
1169NS_IMETHODIMPnsresult
1170AsyncCopyFavicons::Run() {
1171 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"
, 1171); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1171; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1172
1173 IconData icon;
1174
1175 // Ensure we'll callback and dispatch notifications to the main-thread.
1176 auto cleanup = MakeScopeExit([&]() {
1177 // If we bailed out early, just return a null icon uri, since we didn't
1178 // copy anything.
1179 if (!(icon.status & ICON_STATUS_ASSOCIATED1 << 2)) {
1180 icon.spec.Truncate();
1181 }
1182 nsCOMPtr<nsIRunnable> event =
1183 new NotifyIconObservers(icon, mToPage, mCallback);
1184 NS_DispatchToMainThread(event);
1185 });
1186
1187 RefPtr<Database> DB = Database::GetDatabase();
1188 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"
, 1188); return NS_ERROR_UNEXPECTED; } } while (false)
;
1189
1190 nsresult rv = FetchPageInfo(DB, mToPage);
1191 if (rv == NS_ERROR_NOT_AVAILABLE || !mToPage.placeId) {
1192 // We have never seen this page, or we can't add this page to history and
1193 // and it's not a bookmark. We won't add the page.
1194 return NS_OK;
1195 }
1196 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"
, 1196); return rv; } } while (false)
;
1197
1198 // Get just one icon, to check whether the page has any, and to notify
1199 // later.
1200 rv = FetchIconPerSpec(DB, mFromPage.spec, ""_ns, icon, UINT16_MAX(65535));
1201 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"
, 1201); return rv; } } while (false)
;
1202
1203 if (icon.spec.IsEmpty()) {
1204 // There's nothing to copy.
1205 return NS_OK;
1206 }
1207
1208 // Insert an entry in moz_pages_w_icons if needed.
1209 if (!mToPage.id) {
1210 // We need to create the page entry.
1211 nsCOMPtr<mozIStorageStatement> stmt;
1212 stmt = DB->GetStatement(
1213 "INSERT OR IGNORE INTO moz_pages_w_icons (page_url, page_url_hash) "
1214 "VALUES (:page_url, hash(:page_url)) ");
1215 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"
, 1215); return NS_ERROR_UNEXPECTED; } } while (false)
;
1216 mozStorageStatementScoper scoper(stmt);
1217 rv = URIBinder::Bind(stmt, "page_url"_ns, mToPage.spec);
1218 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"
, 1218); return rv; } } while (false)
;
1219 rv = stmt->Execute();
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 // Required to to fetch the id and the guid.
1222 rv = FetchPageInfo(DB, mToPage);
1223 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"
, 1223); return rv; } } while (false)
;
1224 }
1225
1226 // Create the relations.
1227 nsCOMPtr<mozIStorageStatement> stmt = DB->GetStatement(
1228 "INSERT OR IGNORE INTO moz_icons_to_pages (page_id, icon_id, expire_ms) "
1229 "SELECT :id, icon_id, expire_ms "
1230 "FROM moz_icons_to_pages "
1231 "WHERE page_id = (SELECT id FROM moz_pages_w_icons WHERE page_url_hash = "
1232 "hash(:url) AND page_url = :url) ");
1233 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"
, 1233); return NS_ERROR_UNEXPECTED; } } while (false)
;
1234 mozStorageStatementScoper scoper(stmt);
1235 rv = stmt->BindInt64ByName("id"_ns, mToPage.id);
1236 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"
, 1236); return rv; } } while (false)
;
1237 rv = URIBinder::Bind(stmt, "url"_ns, mFromPage.spec);
1238 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"
, 1238); return rv; } } while (false)
;
1239 rv = stmt->Execute();
1240 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"
, 1240); return rv; } } while (false)
;
1241
1242 // Setting this will make us send pageChanged notifications.
1243 // The scope exit will take care of the callback and notifications.
1244 icon.status |= ICON_STATUS_ASSOCIATED1 << 2;
1245
1246 return NS_OK;
1247}
1248
1249} // namespace places
1250} // namespace mozilla