|  | // 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 "include/core/SkCanvas.h" | 
|  | #include "SkFlattenableSerialization.h" | 
|  | #include "include/core/SkImageFilter.h" | 
|  | #include "include/core/SkString.h" | 
|  | #include "src/core/SkOSFile.h" | 
|  |  | 
|  | #include <stdio.h> | 
|  |  | 
|  | static const int kBitmapSize = 24; | 
|  |  | 
|  | static bool read_test_case(const char* filename, SkString* testdata) { | 
|  | FILE* file = sk_fopen(filename, kRead_SkFILE_Flag); | 
|  | if (!file) { | 
|  | SkDebugf("couldn't open file %s\n", filename); | 
|  | return false; | 
|  | } | 
|  | size_t len = sk_fgetsize(file); | 
|  | if (!len) { | 
|  | SkDebugf("couldn't read file %s\n", filename); | 
|  | return false; | 
|  | } | 
|  | testdata->resize(len); | 
|  | (void) fread(testdata->data(), len, file); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | static void run_test_case(const SkString& testdata, const 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 | 
|  | sk_sp<SkImageFilter> flattenable = SkValidatingDeserializeImageFilter(testdata.c_str(), | 
|  | testdata.size()); | 
|  |  | 
|  | // Adding some info, but the test passed if we got here without any trouble | 
|  | if (flattenable != nullptr) { | 
|  | SkDebugf("Valid stream detected.\n"); | 
|  | // Let's see if using the filters can cause any trouble... | 
|  | SkPaint paint; | 
|  | paint.setImageFilter(flattenable); | 
|  | canvas->save(); | 
|  | canvas->clipRect(SkRect::MakeXYWH( | 
|  | 0, 0, SkIntToScalar(kBitmapSize), SkIntToScalar(kBitmapSize))); | 
|  |  | 
|  | // 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); | 
|  |  | 
|  | SkDebugf("Filter DAG rendered successfully.\n"); | 
|  | canvas->restore(); | 
|  | } else { | 
|  | SkDebugf("Invalid stream detected.\n"); | 
|  | } | 
|  | } | 
|  |  | 
|  | static bool read_and_run_test_case(const char* filename, const SkBitmap& bitmap, | 
|  | SkCanvas* canvas) { | 
|  | SkString testdata; | 
|  | SkDebugf("Test case: %s\n", filename); | 
|  | // read_test_case will print a useful error message if it fails. | 
|  | if (!read_test_case(filename, &testdata)) | 
|  | return false; | 
|  | run_test_case(testdata, bitmap, canvas); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | int main(int argc, char** argv) { | 
|  | int ret = 0; | 
|  | SkBitmap bitmap; | 
|  | bitmap.allocN32Pixels(kBitmapSize, kBitmapSize); | 
|  | SkCanvas canvas(bitmap); | 
|  | canvas.clear(0x00000000); | 
|  | for (int i = 1; i < argc; i++) | 
|  | if (!read_and_run_test_case(argv[i], bitmap, &canvas)) | 
|  | ret = 2; | 
|  | // Cluster-Fuzz likes "#EOF" as the last line of output to help distinguish | 
|  | // successful runs from crashes. | 
|  | SkDebugf("#EOF\n"); | 
|  | return ret; | 
|  | } |