#include "content/browser/attribution_reporting/attribution_storage_sql.h"
#include <stddef.h>
#include <stdint.h>
#include <functional>
#include <iterator>
#include <limits>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/containers/enum_set.h"
#include "base/containers/flat_set.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/overloaded.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/numerics/checked_math.h"
#include "base/ranges/algorithm.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/types/expected_macros.h"
#include "base/uuid.h"
#include "components/attribution_reporting/aggregatable_dedup_key.h"
#include "components/attribution_reporting/aggregatable_trigger_config.h"
#include "components/attribution_reporting/aggregatable_trigger_data.h"
#include "components/attribution_reporting/aggregatable_utils.h"
#include "components/attribution_reporting/aggregatable_values.h"
#include "components/attribution_reporting/aggregation_keys.h"
#include "components/attribution_reporting/attribution_scopes_data.h"
#include "components/attribution_reporting/constants.h"
#include "components/attribution_reporting/destination_set.h"
#include "components/attribution_reporting/event_report_windows.h"
#include "components/attribution_reporting/event_trigger_data.h"
#include "components/attribution_reporting/features.h"
#include "components/attribution_reporting/filters.h"
#include "components/attribution_reporting/privacy_math.h"
#include "components/attribution_reporting/source_registration.h"
#include "components/attribution_reporting/source_registration_time_config.mojom-forward.h"
#include "components/attribution_reporting/source_type.mojom.h"
#include "components/attribution_reporting/suitable_origin.h"
#include "components/attribution_reporting/trigger_config.h"
#include "components/attribution_reporting/trigger_data_matching.mojom.h"
#include "components/attribution_reporting/trigger_registration.h"
#include "content/browser/attribution_reporting/aggregatable_attribution_utils.h"
#include "content/browser/attribution_reporting/aggregatable_debug_rate_limit_table.h"
#include "content/browser/attribution_reporting/aggregatable_debug_report.h"
#include "content/browser/attribution_reporting/attribution_features.h"
#include "content/browser/attribution_reporting/attribution_info.h"
#include "content/browser/attribution_reporting/attribution_report.h"
#include "content/browser/attribution_reporting/attribution_reporting.pb.h"
#include "content/browser/attribution_reporting/attribution_resolver_delegate.h"
#include "content/browser/attribution_reporting/attribution_storage_sql_migrations.h"
#include "content/browser/attribution_reporting/attribution_trigger.h"
#include "content/browser/attribution_reporting/common_source_info.h"
#include "content/browser/attribution_reporting/create_report_result.h"
#include "content/browser/attribution_reporting/rate_limit_result.h"
#include "content/browser/attribution_reporting/sql_queries.h"
#include "content/browser/attribution_reporting/sql_utils.h"
#include "content/browser/attribution_reporting/storable_source.h"
#include "content/browser/attribution_reporting/store_source_result.h"
#include "content/browser/attribution_reporting/stored_source.h"
#include "content/public/browser/attribution_data_model.h"
#include "net/base/schemeful_site.h"
#include "services/network/public/cpp/features.h"
#include "sql/database.h"
#include "sql/error_delegate_util.h"
#include "sql/meta_table.h"
#include "sql/recovery.h"
#include "sql/statement.h"
#include "sql/statement_id.h"
#include "sql/transaction.h"
#include "third_party/abseil-cpp/absl/numeric/int128.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/aggregation_service/aggregatable_report.mojom.h"
#include "url/origin.h"
namespace content {
namespace {
AggregatableResult;
EventLevelResult;
AggregatableTriggerConfig;
AttributionScopesData;
EventReportWindows;
SuitableOrigin;
SourceType;
TriggerDataMatching;
const base::FilePath::CharType kDatabasePath[] = …);
constexpr int64_t kUnsetRecordId = …;
void RecordInitializationStatus(
const AttributionStorageSql::InitStatus status) { … }
void RecordSourcesDeleted(int count) { … }
void RecordReportsDeleted(int event_count, int aggregatable_count) { … }
int64_t SerializeUint64(uint64_t data) { … }
uint64_t DeserializeUint64(int64_t data) { … }
int64_t SerializeUint64(int64_t data) = delete;
uint64_t DeserializeUint64(uint64_t data) = delete;
int SerializeAttributionLogic(StoredSource::AttributionLogic val) { … }
std::optional<StoredSource::AttributionLogic> DeserializeAttributionLogic(
int val) { … }
int SerializeSourceType(SourceType val) { … }
int SerializeReportType(AttributionReport::Type val) { … }
std::optional<AttributionReport::Type> DeserializeReportType(int val) { … }
std::optional<StoredSource::ActiveState> GetSourceActiveState(
bool event_level_active,
bool aggregatable_active) { … }
void BindUint64OrNull(sql::Statement& statement,
int col,
std::optional<uint64_t> value) { … }
std::optional<uint64_t> ColumnUint64OrNull(sql::Statement& statement, int col) { … }
constexpr int kSourceColumnCount = …;
int64_t GetStorageFileSizeKB(const base::FilePath& path_to_database) { … }
}
struct AttributionStorageSql::ReportCorruptionStatusSetAndIds { … };
base::expected<AttributionStorageSql::StoredSourceData,
AttributionStorageSql::ReportCorruptionStatusSetAndIds>
AttributionStorageSql::ReadSourceFromStatement(sql::Statement& statement) { … }
std::optional<AttributionStorageSql::StoredSourceData>
AttributionStorageSql::ReadSourceToAttribute(StoredSource::Id source_id) { … }
namespace {
base::FilePath DatabasePath(const base::FilePath& user_data_directory) { … }
void AssignSourceForDeactivationOrDeletion(
StoredSource::Id source_id,
bool has_reports,
std::vector<StoredSource::Id>& source_ids_to_delete,
std::vector<StoredSource::Id>& source_ids_to_deactivate) { … }
}
std::unique_ptr<AttributionStorageSql::Transaction>
AttributionStorageSql::Transaction::CreateAndStart(sql::Database& db) { … }
AttributionStorageSql::Transaction::Transaction(sql::Database& db)
: … { … }
AttributionStorageSql::Transaction::~Transaction() = default;
bool AttributionStorageSql::Transaction::Commit() { … }
AttributionStorageSql::AttributionStorageSql(
const base::FilePath& user_data_directory,
AttributionResolverDelegate* delegate)
: … { … }
AttributionStorageSql::~AttributionStorageSql() { … }
std::unique_ptr<AttributionStorageSql::Transaction>
AttributionStorageSql::StartTransaction() { … }
bool AttributionStorageSql::DeactivateSources(
const std::vector<StoredSource::Id>& sources) { … }
bool AttributionStorageSql::DeactivateSourcesForDestinationLimit(
const std::vector<StoredSource::Id>& sources,
base::Time now) { … }
std::optional<StoredSource> AttributionStorageSql::InsertSource(
const StorableSource& source,
base::Time source_time,
int num_attributions,
bool event_level_active,
double randomized_response_rate,
StoredSource::AttributionLogic attribution_logic,
base::Time aggregatable_report_window_time) { … }
base::expected<std::optional<AttributionStorageSql::ReportIdAndPriority>,
AttributionStorageSql::Error>
AttributionStorageSql::GetReportWithMinPriority(StoredSource::Id source_id,
base::Time report_time) { … }
bool AttributionStorageSql::DeactivateSourceAtEventLevel(StoredSource::Id id) { … }
bool AttributionStorageSql::RemoveScopesDataForSource(
StoredSource::Id source_id) { … }
namespace {
void PrepareGetMatchingSourcesStatement(
sql::Statement& stmt,
base::span<const net::SchemefulSite> destinations) { … }
}
bool AttributionStorageSql::UpdateOrRemoveSourcesWithIncompatibleScopeFields(
const StorableSource& pending_source,
base::Time source_time) { … }
bool AttributionStorageSql::RemoveSourcesWithOutdatedScopes(
const StorableSource& source,
base::Time source_time) { … }
bool AttributionStorageSql::FindMatchingSourceForTrigger(
const AttributionTrigger& trigger,
base::Time trigger_time,
std::optional<StoredSource::Id>& source_id_to_attribute,
std::vector<StoredSource::Id>& source_ids_to_delete,
std::vector<StoredSource::Id>& source_ids_to_deactivate) { … }
bool AttributionStorageSql::IncrementNumAttributions(StoredSource::Id id) { … }
base::expected<AttributionReport,
AttributionStorageSql::ReportCorruptionStatusSetAndIds>
AttributionStorageSql::ReadReportFromStatement(sql::Statement& statement) { … }
std::vector<AttributionReport> AttributionStorageSql::GetAttributionReports(
base::Time max_report_time,
int limit) { … }
std::optional<base::Time> AttributionStorageSql::GetNextReportTime(
base::Time time) { … }
std::optional<AttributionReport> AttributionStorageSql::GetReport(
AttributionReport::Id id) { … }
bool AttributionStorageSql::DeleteExpiredSources() { … }
bool AttributionStorageSql::DeleteReport(AttributionReport::Id report_id) { … }
bool AttributionStorageSql::DeleteReportInternal(
AttributionReport::Id report_id) { … }
bool AttributionStorageSql::DeleteEventLevelReportsTriggeredLaterThanForSources(
const std::vector<StoredSource::Id>& sources,
base::Time source_time) { … }
bool AttributionStorageSql::UpdateReportForSendFailure(
AttributionReport::Id report_id,
base::Time new_report_time) { … }
bool AttributionStorageSql::AdjustOfflineReportTimes(
base::TimeDelta min_delay,
base::TimeDelta max_delay) { … }
void AttributionStorageSql::ClearDataWithFilter(
base::Time delete_begin,
base::Time delete_end,
StoragePartition::StorageKeyMatcherFunction filter,
bool delete_rate_limit_data) { … }
void AttributionStorageSql::ClearAllDataAllTime(bool delete_rate_limit_data) { … }
int64_t AttributionStorageSql::CountActiveSourcesWithSourceOrigin(
const SuitableOrigin& origin,
const base::Time now) { … }
int64_t AttributionStorageSql::CountReportsWithDestinationSite(
const net::SchemefulSite& destination,
AttributionReport::Type report_type) { … }
std::vector<StoredSource> AttributionStorageSql::GetActiveSources(int limit) { … }
bool AttributionStorageSql::ReadDedupKeys(
StoredSource::Id source_id,
std::vector<uint64_t>& event_level_dedup_keys,
std::vector<uint64_t>& aggregatable_dedup_keys) { … }
bool AttributionStorageSql::StoreDedupKey(StoredSource::Id source_id,
uint64_t dedup_key,
AttributionReport::Type report_type) { … }
void AttributionStorageSql::HandleInitializationFailure(
const InitStatus status) { … }
bool AttributionStorageSql::LazyInit(DbCreationPolicy creation_policy) { … }
std::optional<int64_t> AttributionStorageSql::NumberOfSources() { … }
void AttributionStorageSql::VerifyReports(DeletionCounts* deletion_counts) { … }
void AttributionStorageSql::RecordSourcesPerSourceOrigin() { … }
bool AttributionStorageSql::InitializeSchema(bool db_empty) { … }
bool AttributionStorageSql::CreateSchema() { … }
void AttributionStorageSql::DatabaseErrorCallback(int extended_error,
sql::Statement* stmt) { … }
bool AttributionStorageSql::DeleteSources(
const std::vector<StoredSource::Id>& source_ids) { … }
bool AttributionStorageSql::ClearReportsForOriginsInRange(
base::Time delete_begin,
base::Time delete_end,
StoragePartition::StorageKeyMatcherFunction filter,
std::vector<StoredSource::Id>& source_ids_to_delete,
int& num_event_reports_deleted,
int& num_aggregatable_reports_deleted) { … }
bool AttributionStorageSql::ClearReportsForSourceIds(
const std::vector<StoredSource::Id>& source_ids,
int& num_event_reports_deleted,
int& num_aggregatable_reports_deleted) { … }
RateLimitResult
AttributionStorageSql::AggregatableAttributionAllowedForBudgetLimit(
const AttributionReport::AggregatableAttributionData&
aggregatable_attribution,
int remaining_aggregatable_attribution_budget) { … }
bool AttributionStorageSql::AdjustBudgetConsumedForSource(
StoredSource::Id source_id,
int additional_budget_consumed) { … }
std::optional<AttributionReport::Id>
AttributionStorageSql::StoreAttributionReport(
StoredSource::Id source_id,
base::Time trigger_time,
base::Time initial_report_time,
const base::Uuid& external_report_id,
std::optional<uint64_t> trigger_debug_key,
const SuitableOrigin& context_origin,
const SuitableOrigin& reporting_origin,
uint32_t trigger_data,
int64_t priority) { … }
[[nodiscard]] std::optional<AttributionReport::Id>
AttributionStorageSql::StoreNullReport(
base::Time trigger_time,
base::Time initial_report_time,
const base::Uuid& external_report_id,
std::optional<uint64_t> trigger_debug_key,
const attribution_reporting::SuitableOrigin& context_origin,
const attribution_reporting::SuitableOrigin& reporting_origin,
const std::optional<SuitableOrigin>& coordinator_origin,
const AggregatableTriggerConfig& trigger_config,
base::Time fake_source_time) { … }
[[nodiscard]] std::optional<AttributionReport::Id>
AttributionStorageSql::StoreAggregatableReport(
StoredSource::Id source_id,
base::Time trigger_time,
base::Time initial_report_time,
const base::Uuid& external_report_id,
std::optional<uint64_t> trigger_debug_key,
const attribution_reporting::SuitableOrigin& context_origin,
const attribution_reporting::SuitableOrigin& reporting_origin,
const std::optional<SuitableOrigin>& coordinator_origin,
const AggregatableTriggerConfig& trigger_config,
const std::vector<blink::mojom::AggregatableReportHistogramContribution>&
contributions) { … }
std::optional<AttributionReport::Id>
AttributionStorageSql::StoreAttributionReport(
int64_t source_id,
base::Time trigger_time,
base::Time initial_report_time,
const base::Uuid& external_report_id,
std::optional<uint64_t> trigger_debug_key,
const SuitableOrigin& context_origin,
const SuitableOrigin& reporting_origin,
AttributionReport::Type report_type,
const std::string& serialized_metadata) { … }
AggregatableResult
AttributionStorageSql::MaybeStoreAggregatableAttributionReportData(
AttributionReport& report,
StoredSource::Id source_id,
int remaining_aggregatable_attribution_budget,
int num_aggregatable_attribution_reports,
std::optional<uint64_t> dedup_key,
std::optional<int>& max_aggregatable_reports_per_source) { … }
std::set<AttributionDataModel::DataKey>
AttributionStorageSql::GetAllDataKeys() { … }
std::optional<AttributionStorageSql::AggregatableDebugSourceData>
AttributionStorageSql::GetAggregatableDebugSourceData(
StoredSource::Id source_id) { … }
int64_t AttributionStorageSql::StorageFileSizeKB() { … }
AggregatableDebugRateLimitTable::Result
AttributionStorageSql::AggregatableDebugReportAllowedForRateLimit(
const AggregatableDebugReport& report) { … }
bool AttributionStorageSql::AdjustAggregatableDebugSourceData(
StoredSource::Id source_id,
int additional_budget_consumed) { … }
bool AttributionStorageSql::AdjustForAggregatableDebugReport(
const AggregatableDebugReport& report,
std::optional<StoredSource::Id> source_id) { … }
void AttributionStorageSql::SetDelegate(AttributionResolverDelegate* delegate) { … }
bool AttributionStorageSql::AddRateLimitForSource(
const StoredSource& source,
int64_t destination_limit_priority) { … }
bool AttributionStorageSql::AddRateLimitForAttribution(
const AttributionInfo& attribution_info,
const StoredSource& source,
RateLimitTable::Scope scope,
AttributionReport::Id id) { … }
RateLimitResult AttributionStorageSql::SourceAllowedForReportingOriginLimit(
const StorableSource& source,
base::Time source_time) { … }
RateLimitResult
AttributionStorageSql::SourceAllowedForReportingOriginPerSiteLimit(
const StorableSource& source,
base::Time source_time) { … }
RateLimitTable::DestinationRateLimitResult
AttributionStorageSql::SourceAllowedForDestinationRateLimit(
const StorableSource& source,
base::Time source_time) { … }
RateLimitResult
AttributionStorageSql::SourceAllowedForDestinationPerDayRateLimit(
const StorableSource& source,
base::Time source_time) { … }
RateLimitResult
AttributionStorageSql::AttributionAllowedForReportingOriginLimit(
const AttributionInfo& attribution_info,
const StoredSource& source) { … }
RateLimitResult AttributionStorageSql::AttributionAllowedForAttributionLimit(
const AttributionInfo& attribution_info,
const StoredSource& source,
RateLimitTable::Scope scope) { … }
base::expected<std::vector<StoredSource::Id>, RateLimitTable::Error>
AttributionStorageSql::GetSourcesToDeactivateForDestinationLimit(
const StorableSource& source,
base::Time source_time) { … }
bool AttributionStorageSql::DeleteAttributionRateLimit(
RateLimitTable::Scope scope,
AttributionReport::Id report_id) { … }
}