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