1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/file_util.h"
6#include "base/logging.h"
7#include "third_party/skia/include/core/SkBitmapDevice.h"
8#include "third_party/skia/include/core/SkCanvas.h"
9#include "third_party/skia/include/core/SkFlattenableSerialization.h"
10#include "third_party/skia/include/core/SkImageFilter.h"
11
12namespace {
13
14static const int BitmapSize = 24;
15
16bool ReadTestCase(const char* filename, std::string* ipc_filter_message) {
17  base::FilePath filepath = base::FilePath::FromUTF8Unsafe(filename);
18
19  if (!base::ReadFileToString(filepath, ipc_filter_message)) {
20    LOG(ERROR) << filename << ": couldn't read file.";
21    return false;
22  }
23
24  return true;
25}
26
27void RunTestCase(std::string& ipc_filter_message, SkBitmap& bitmap,
28                 SkCanvas* canvas) {
29  // This call shouldn't crash or cause ASAN to flag any memory issues
30  // If nothing bad happens within this call, everything is fine
31  SkFlattenable* flattenable = SkValidatingDeserializeFlattenable(
32        ipc_filter_message.c_str(), ipc_filter_message.size(),
33        SkImageFilter::GetFlattenableType());
34
35  // Adding some info, but the test passed if we got here without any trouble
36  if (flattenable != NULL) {
37    LOG(INFO) << "Valid stream detected.";
38    // Let's see if using the filters can cause any trouble...
39    SkPaint paint;
40    paint.setImageFilter(static_cast<SkImageFilter*>(flattenable))->unref();
41    canvas->save();
42    canvas->clipRect(SkRect::MakeXYWH(
43        0, 0, SkIntToScalar(BitmapSize), SkIntToScalar(BitmapSize)));
44
45    // This call shouldn't crash or cause ASAN to flag any memory issues
46    // If nothing bad happens within this call, everything is fine
47    canvas->drawBitmap(bitmap, 0, 0, &paint);
48
49    LOG(INFO) << "Filter DAG rendered successfully";
50    canvas->restore();
51  } else {
52    LOG(INFO) << "Invalid stream detected.";
53  }
54}
55
56bool ReadAndRunTestCase(const char* filename, SkBitmap& bitmap,
57                        SkCanvas* canvas) {
58  std::string ipc_filter_message;
59
60  LOG(INFO) << "Test case: " << filename;
61
62  // ReadTestCase will print a useful error message if it fails.
63  if (!ReadTestCase(filename, &ipc_filter_message))
64    return false;
65
66  RunTestCase(ipc_filter_message, bitmap, canvas);
67
68  return true;
69}
70
71}
72
73int main(int argc, char** argv) {
74  int ret = 0;
75
76  SkBitmap bitmap;
77  bitmap.setConfig(SkBitmap::kARGB_8888_Config, BitmapSize, BitmapSize);
78  bitmap.allocPixels();
79  SkBitmapDevice device(bitmap);
80  SkCanvas canvas(&device);
81  canvas.clear(0x00000000);
82
83  for (int i = 1; i < argc; i++)
84    if (!ReadAndRunTestCase(argv[i], bitmap, &canvas))
85      ret = 2;
86
87  // Cluster-Fuzz likes "#EOF" as the last line of output to help distinguish
88  // successful runs from crashes.
89  printf("#EOF\n");
90
91  return ret;
92}
93
94