// 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.

#include <fuzzer/FuzzedDataProvider.h>

#include <algorithm>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/task_environment.h"
#include "base/test/test_discardable_memory_allocator.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_util.h"
#include "ui/gfx/render_text.h"

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "third_party/test_fonts/fontconfig/fontconfig_util_linux.h"
#endif

namespace {

#if BUILDFLAG(IS_WIN)
const char kFontDescription[] = "Segoe UI, 13px";
#elif BUILDFLAG(IS_ANDROID)
const char kFontDescription[] = "serif, 13px";
#else
const char kFontDescription[] = "sans, 13px";
#endif

struct Environment {
  Environment()
      : task_environment((base::CommandLine::Init(0, nullptr),
                          TestTimeouts::Initialize(),
                          base::test::TaskEnvironment::MainThreadType::UI)) {
    logging::SetMinLogLevel(logging::LOG_FATAL);

    // Some platforms require discardable memory to use bitmap fonts.
    base::DiscardableMemoryAllocator::SetInstance(
        &discardable_memory_allocator);

    CHECK(base::i18n::InitializeICU());

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
    test_fonts::SetUpFontconfig();
#endif
    gfx::InitializeFonts();
    gfx::FontList::SetDefaultFontDescription(kFontDescription);
  }

  base::TestDiscardableMemoryAllocator discardable_memory_allocator;
  base::AtExitManager at_exit_manager;
  base::test::TaskEnvironment task_environment;
};

// Commands recognized to drive the API calls on RenderText.
enum class RenderTextAPI {
  kDraw,
  kSetText,
  kAppendText,
  kSetHorizontalAlignment,
  kSetVerticalAlignment,
  kSetCursorEnabled,
  kSetSelectionColor,
  kSetSelectionBackgroundFocusedColor,
  kSetSymmetricSelectionVisualBounds,
  kSetFocused,
  kSetClipToDisplayRect,
  kSetObscured,
  kSetObscuredRevealIndex,
  kSetMultiline,
  kSetMaxLines,
  kSetWordWrapBehavior,
  kSetWhitespaceElision,
  kSetSubpixelRenderingSuppressed,
  kSetColor,
  kApplyColor,
  kSetStyle,
  kApplyStyle,
  kSetWeight,
  kApplyWeight,
  kSetDirectionalityMode,
  kSetElideBehavior,
  kIsGraphemeBoundary,
  kIndexOfAdjacentGrapheme,
  kSetObscuredGlyphSpacing,
  kSetDisplayRect,
  kGetSubstringBounds,
  kGetCursorSpan,
  kMaxValue = kGetCursorSpan
};

gfx::DirectionalityMode ConsumeDirectionalityMode(FuzzedDataProvider* fdp) {
  if (fdp->ConsumeBool())
    return gfx::DIRECTIONALITY_FORCE_RTL;
  return gfx::DIRECTIONALITY_FORCE_LTR;
}

gfx::HorizontalAlignment ConsumeHorizontalAlignment(FuzzedDataProvider* fdp) {
  switch (fdp->ConsumeIntegralInRange(0, 4)) {
    case 0:
      return gfx::ALIGN_LEFT;
    case 1:
      return gfx::ALIGN_CENTER;
    case 2:
      return gfx::ALIGN_RIGHT;
    case 3:
      return gfx::ALIGN_TO_HEAD;
    default:
      return gfx::ALIGN_LEFT;
  }
}

gfx::VerticalAlignment ConsumeVerticalAlignment(FuzzedDataProvider* fdp) {
  switch (fdp->ConsumeIntegralInRange(0, 3)) {
    case 0:
      return gfx::ALIGN_TOP;
    case 1:
      return gfx::ALIGN_MIDDLE;
    case 2:
      return gfx::ALIGN_BOTTOM;
    default:
      return gfx::ALIGN_TOP;
  }
}

gfx::TextStyle ConsumeStyle(FuzzedDataProvider* fdp) {
  switch (fdp->ConsumeIntegralInRange(0, 4)) {
    case 0:
      return gfx::TEXT_STYLE_ITALIC;
    case 1:
      return gfx::TEXT_STYLE_STRIKE;
    case 2:
      return gfx::TEXT_STYLE_UNDERLINE;
    case 3:
      return gfx::TEXT_STYLE_HEAVY_UNDERLINE;
    default:
      return gfx::TEXT_STYLE_ITALIC;
  }
}

gfx::WordWrapBehavior ConsumeWordWrap(FuzzedDataProvider* fdp) {
  // TODO(1150235): ELIDE_LONG_WORDS is not supported.
  switch (fdp->ConsumeIntegralInRange(0, 3)) {
    case 0:
      return gfx::IGNORE_LONG_WORDS;
    case 1:
      return gfx::TRUNCATE_LONG_WORDS;
    case 2:
      return gfx::WRAP_LONG_WORDS;
    default:
      return gfx::IGNORE_LONG_WORDS;
  }
}

gfx::ElideBehavior ConsumeElideBehavior(FuzzedDataProvider* fdp,
                                        bool generate_only_homogeneous_styles) {
  if (generate_only_homogeneous_styles) {
    // The styles are guaranteed to be homogenous and it is safe to generate
    // any eliding behavior.
    switch (fdp->ConsumeIntegralInRange(0, 7)) {
      case 0:
        return gfx::NO_ELIDE;
      case 1:
        return gfx::TRUNCATE;
      case 2:
        return gfx::ELIDE_HEAD;
      case 3:
        return gfx::ELIDE_MIDDLE;
      case 4:
        return gfx::ELIDE_TAIL;
      case 5:
        return gfx::ELIDE_EMAIL;
      case 6:
        return gfx::FADE_TAIL;
      default:
        return gfx::NO_ELIDE;
    }
  } else {
    // Only generate eliding behaviors that are compatible with non homogeneous
    // text. Remove this when http://crbug.com/1085014 is fixed.
    switch (fdp->ConsumeIntegralInRange(0, 4)) {
      case 0:
        return gfx::NO_ELIDE;
      case 1:
        return gfx::TRUNCATE;
      case 2:
        return gfx::ELIDE_TAIL;
      case 3:
        return gfx::FADE_TAIL;
      default:
        return gfx::NO_ELIDE;
    }
  }
}

gfx::LogicalCursorDirection ConsumeLogicalCursorDirection(
    FuzzedDataProvider* fdp) {
  switch (fdp->ConsumeIntegralInRange(0, 1)) {
    case 0:
      return gfx::CURSOR_BACKWARD;
    default:
      return gfx::CURSOR_FORWARD;
  }
}

gfx::Font::Weight ConsumeWeight(FuzzedDataProvider* fdp) {
  if (fdp->ConsumeBool())
    return gfx::Font::Weight::BOLD;
  return gfx::Font::Weight::NORMAL;
}

SkColor ConsumeSkColor(FuzzedDataProvider* fdp) {
  return static_cast<SkColor>(fdp->ConsumeIntegral<uint32_t>());
}

gfx::Range ConsumeRange(FuzzedDataProvider* fdp, size_t max) {
  size_t start = fdp->ConsumeIntegralInRange<size_t>(0, max);
  size_t end = fdp->ConsumeIntegralInRange<size_t>(start, max);
  return gfx::Range(start, end);
}

// Eliding behaviors are not all fully supported by RenderText. Ignore
// unsupported cases. This is causing clusterfuzz to fail with invalid
// tests (http://crbug.com/1185542). Remove when https://crbug.com/1085014 is
// fixed.
bool DoesDisplayRangeSupportElideBehavior(const gfx::RenderText* render_text) {
  const gfx::ElideBehavior behavior = render_text->elide_behavior();
  return behavior != gfx::ELIDE_HEAD && behavior != gfx::ELIDE_MIDDLE &&
         behavior != gfx::ELIDE_EMAIL;
}

const int kMaxStringLength = 128;

}  // anonymous namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment env;

  std::unique_ptr<gfx::RenderText> render_text =
      gfx::RenderText::CreateRenderText();
  gfx::Canvas canvas;

  FuzzedDataProvider fdp(data, size);
  if (size == 0)
    return 0;

  // Eliding and Styles are not well supported by RenderText. DCHECKs are
  // present in RenderText code to avoid any incorrect uses but the fuzzer
  // should not generate them until full support (http://crbug.com/1283159).
  const bool generate_only_homogeneous_styles = fdp.ConsumeBool();

  while (fdp.remaining_bytes() != 0) {
    const RenderTextAPI command = fdp.ConsumeEnum<RenderTextAPI>();
    switch (command) {
      case RenderTextAPI::kDraw:
        render_text->Draw(&canvas);
        break;

      case RenderTextAPI::kSetText:
        render_text->SetText(
            base::UTF8ToUTF16(fdp.ConsumeRandomLengthString(kMaxStringLength)));
        break;

      case RenderTextAPI::kAppendText:
        render_text->AppendText(
            base::UTF8ToUTF16(fdp.ConsumeRandomLengthString(kMaxStringLength)));
        break;

      case RenderTextAPI::kSetHorizontalAlignment:
        render_text->SetHorizontalAlignment(ConsumeHorizontalAlignment(&fdp));
        break;

      case RenderTextAPI::kSetVerticalAlignment:
        render_text->SetVerticalAlignment(ConsumeVerticalAlignment(&fdp));
        break;

      case RenderTextAPI::kSetCursorEnabled:
        render_text->SetCursorEnabled(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetSelectionColor:
        render_text->set_selection_color(ConsumeSkColor(&fdp));
        break;

      case RenderTextAPI::kSetSelectionBackgroundFocusedColor:
        render_text->set_selection_background_focused_color(
            ConsumeSkColor(&fdp));
        break;

      case RenderTextAPI::kSetSymmetricSelectionVisualBounds:
        render_text->set_symmetric_selection_visual_bounds(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetFocused:
        render_text->set_focused(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetClipToDisplayRect:
        render_text->set_clip_to_display_rect(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetObscured:
        render_text->SetObscured(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetObscuredRevealIndex:
        render_text->SetObscuredRevealIndex(fdp.ConsumeIntegralInRange<size_t>(
            0, render_text->text().length()));
        break;

      case RenderTextAPI::kSetMultiline:
        if (generate_only_homogeneous_styles) {
          render_text->SetMultiline(fdp.ConsumeBool());
        }
        break;

      case RenderTextAPI::kSetMaxLines:
        render_text->SetMaxLines(fdp.ConsumeIntegralInRange<size_t>(0, 5));
        break;

      case RenderTextAPI::kSetWordWrapBehavior:
        render_text->SetWordWrapBehavior(ConsumeWordWrap(&fdp));
        break;

      case RenderTextAPI::kSetWhitespaceElision:
        render_text->SetWhitespaceElision(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetSubpixelRenderingSuppressed:
        render_text->set_subpixel_rendering_suppressed(fdp.ConsumeBool());
        break;

      case RenderTextAPI::kSetColor:
        render_text->SetColor(ConsumeSkColor(&fdp));
        break;

      case RenderTextAPI::kApplyColor:
        if (!generate_only_homogeneous_styles) {
          render_text->ApplyColor(
              ConsumeSkColor(&fdp),
              ConsumeRange(&fdp, render_text->text().length()));
        }
        break;

      case RenderTextAPI::kSetStyle:
        render_text->SetStyle(ConsumeStyle(&fdp), fdp.ConsumeBool());
        break;

      case RenderTextAPI::kApplyStyle:
        if (!generate_only_homogeneous_styles) {
          render_text->ApplyStyle(
              ConsumeStyle(&fdp), fdp.ConsumeBool(),
              ConsumeRange(&fdp, render_text->text().length()));
        }
        break;

      case RenderTextAPI::kSetWeight:
        render_text->SetWeight(ConsumeWeight(&fdp));
        break;

      case RenderTextAPI::kApplyWeight:
        if (!generate_only_homogeneous_styles) {
          render_text->ApplyWeight(
              ConsumeWeight(&fdp),
              ConsumeRange(&fdp, render_text->text().length()));
        }
        break;

      case RenderTextAPI::kSetDirectionalityMode:
        render_text->SetDirectionalityMode(ConsumeDirectionalityMode(&fdp));
        break;

      case RenderTextAPI::kSetElideBehavior:
        render_text->SetElideBehavior(
            ConsumeElideBehavior(&fdp, generate_only_homogeneous_styles));
        break;

      case RenderTextAPI::kIsGraphemeBoundary:
        render_text->IsGraphemeBoundary(fdp.ConsumeIntegralInRange<size_t>(
            0, render_text->text().length()));
        break;

      case RenderTextAPI::kIndexOfAdjacentGrapheme: {
        size_t index = render_text->IndexOfAdjacentGrapheme(
            fdp.ConsumeIntegralInRange<size_t>(0, render_text->text().length()),
            ConsumeLogicalCursorDirection(&fdp));
        bool is_grapheme = render_text->IsGraphemeBoundary(index);
        DCHECK(is_grapheme);
        break;
      }
      case RenderTextAPI::kSetObscuredGlyphSpacing:
        render_text->SetObscuredGlyphSpacing(
            fdp.ConsumeIntegralInRange<size_t>(0, 10));
        break;
      case RenderTextAPI::kSetDisplayRect:
        render_text->SetDisplayRect(
            gfx::Rect(fdp.ConsumeIntegralInRange<int>(-30, 30),
                      fdp.ConsumeIntegralInRange<int>(-30, 30),
                      fdp.ConsumeIntegralInRange<int>(0, 200),
                      fdp.ConsumeIntegralInRange<int>(0, 30)));
        break;
      case RenderTextAPI::kGetSubstringBounds:
        // RenderText doesn't support that case (https://crbug.com/1085014).
        if (!DoesDisplayRangeSupportElideBehavior(render_text.get()))
          break;

        render_text->GetSubstringBounds(
            ConsumeRange(&fdp, render_text->text().length()));
        break;
      case RenderTextAPI::kGetCursorSpan:
        // RenderText doesn't support that case (https://crbug.com/1085014).
        if (!DoesDisplayRangeSupportElideBehavior(render_text.get()))
          break;

        render_text->GetCursorSpan(
            ConsumeRange(&fdp, render_text->text().length()));
        break;
    }
  }

  return 0;
}
