1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84

media / learning / impl / learning_fuzzertest.cc [blame]

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/374320451): Fix and remove.
#pragma allow_unsafe_buffers
#endif

#include <fuzzer/FuzzedDataProvider.h>

#include "base/test/task_environment.h"
#include "media/learning/impl/learning_task_controller_impl.h"

using media::learning::FeatureValue;
using media::learning::FeatureVector;
using media::learning::LearningTask;
using ValueDescription = media::learning::LearningTask::ValueDescription;
using media::learning::LearningTaskControllerImpl;
using media::learning::ObservationCompletion;
using media::learning::TargetValue;

ValueDescription ConsumeValueDescription(FuzzedDataProvider* provider) {
  ValueDescription desc;
  desc.name = provider->ConsumeRandomLengthString(100);
  desc.ordering = provider->ConsumeEnum<LearningTask::Ordering>();
  desc.privacy_mode = provider->ConsumeEnum<LearningTask::PrivacyMode>();
  return desc;
}

double ConsumeDouble(FuzzedDataProvider* provider) {
  std::vector<uint8_t> v = provider->ConsumeBytes<uint8_t>(sizeof(double));
  if (v.size() == sizeof(double))
    return reinterpret_cast<double*>(v.data())[0];

  return 0;
}

FeatureVector ConsumeFeatureVector(FuzzedDataProvider* provider) {
  FeatureVector features;
  int n = provider->ConsumeIntegralInRange(0, 100);
  while (n-- > 0)
    features.push_back(FeatureValue(ConsumeDouble(provider)));

  return features;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  base::test::TaskEnvironment task_environment;
  FuzzedDataProvider provider(data, size);

  LearningTask task;
  task.name = provider.ConsumeRandomLengthString(100);
  task.model = provider.ConsumeEnum<LearningTask::Model>();
  task.use_one_hot_conversion = provider.ConsumeBool();
  task.uma_hacky_aggregate_confusion_matrix = provider.ConsumeBool();
  task.uma_hacky_by_training_weight_confusion_matrix = provider.ConsumeBool();
  task.uma_hacky_by_feature_subset_confusion_matrix = provider.ConsumeBool();
  int n_features = provider.ConsumeIntegralInRange(0, 100);
  int subset_size = provider.ConsumeIntegralInRange<uint8_t>(0, n_features);
  if (subset_size)
    task.feature_subset_size = subset_size;
  for (int i = 0; i < n_features; i++)
    task.feature_descriptions.push_back(ConsumeValueDescription(&provider));
  task.target_description = ConsumeValueDescription(&provider);

  LearningTaskControllerImpl controller(task);

  // Build random examples.
  while (provider.remaining_bytes() > 0) {
    base::UnguessableToken id = base::UnguessableToken::Create();
    std::optional<TargetValue> default_target;
    if (provider.ConsumeBool())
      default_target = TargetValue(ConsumeDouble(&provider));
    controller.BeginObservation(id, ConsumeFeatureVector(&provider),
                                default_target, std::nullopt);
    controller.CompleteObservation(
        id, ObservationCompletion(TargetValue(ConsumeDouble(&provider)),
                                  ConsumeDouble(&provider)));
    task_environment.RunUntilIdle();
  }

  return 0;
}