// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/files/file_util.h" #include "base/logging.h" #include "base/test/test_discardable_memory_allocator.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkFlattenableSerialization.h" #include "third_party/skia/include/core/SkImageFilter.h" namespace { static const int BitmapSize = 24; bool ReadTestCase(const char* filename, std::string* ipc_filter_message) { base::FilePath filepath = base::FilePath::FromUTF8Unsafe(filename); if (!base::ReadFileToString(filepath, ipc_filter_message)) { LOG(ERROR) << filename << ": couldn't read file."; return false; } return true; } void RunTestCase(std::string& ipc_filter_message, SkBitmap& bitmap, SkCanvas* canvas) { // This call shouldn't crash or cause ASAN to flag any memory issues // If nothing bad happens within this call, everything is fine SkFlattenable* flattenable = SkValidatingDeserializeFlattenable( ipc_filter_message.c_str(), ipc_filter_message.size(), SkImageFilter::GetFlattenableType()); // Adding some info, but the test passed if we got here without any trouble if (flattenable != NULL) { LOG(INFO) << "Valid stream detected."; // Let's see if using the filters can cause any trouble... SkPaint paint; paint.setImageFilter(static_cast(flattenable))->unref(); canvas->save(); canvas->clipRect(SkRect::MakeXYWH( 0, 0, SkIntToScalar(BitmapSize), SkIntToScalar(BitmapSize))); // This call shouldn't crash or cause ASAN to flag any memory issues // If nothing bad happens within this call, everything is fine canvas->drawBitmap(bitmap, 0, 0, &paint); LOG(INFO) << "Filter DAG rendered successfully"; canvas->restore(); } else { LOG(INFO) << "Invalid stream detected."; } } bool ReadAndRunTestCase(const char* filename, SkBitmap& bitmap, SkCanvas* canvas) { std::string ipc_filter_message; LOG(INFO) << "Test case: " << filename; // ReadTestCase will print a useful error message if it fails. if (!ReadTestCase(filename, &ipc_filter_message)) return false; RunTestCase(ipc_filter_message, bitmap, canvas); return true; } } int main(int argc, char** argv) { int ret = 0; base::TestDiscardableMemoryAllocator discardable_memory_allocator; base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator); SkBitmap bitmap; bitmap.allocN32Pixels(BitmapSize, BitmapSize); SkCanvas canvas(bitmap); canvas.clear(0x00000000); for (int i = 1; i < argc; i++) if (!ReadAndRunTestCase(argv[i], bitmap, &canvas)) ret = 2; // Cluster-Fuzz likes "#EOF" as the last line of output to help distinguish // successful runs from crashes. printf("#EOF\n"); return ret; }