Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(488)

Unified Diff: fuzz/fuzz.cpp

Issue 1591073002: Add ability to fuzz images and skps to fuzz binary (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Fix imports Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: fuzz/fuzz.cpp
diff --git a/fuzz/fuzz.cpp b/fuzz/fuzz.cpp
index 343e25b45303527a8a5cbfb5cc33bcebfb747afa..037c3b8a546c807929deeb428e8c26b8eea0e96a 100644
--- a/fuzz/fuzz.cpp
+++ b/fuzz/fuzz.cpp
@@ -6,33 +6,160 @@
*/
#include "Fuzz.h"
+#include "SkCanvas.h"
+#include "SkCodec.h"
#include "SkCommandLineFlags.h"
+#include "SkData.h"
+#include "SkImage.h"
+#include "SkImageEncoder.h"
+#include "SkMallocPixelRef.h"
+#include "SkPicture.h"
+#include "SkStream.h"
+
#include <signal.h>
#include <stdlib.h>
+#include <cmath>
-DEFINE_string2(bytes, b, "", "A path to a file containing fuzzed bytes.");
+DEFINE_string2(bytes, b, "", "A path to a file.");
mtklein 2016/01/20 14:49:06 ? Do they not contain fuzzed bytes any more?
kjlubick 2016/01/20 19:21:58 Done.
DEFINE_string2(match, m, "", "The usual --match, applied to DEF_FUZZ names.");
+DEFINE_string(mode, "api", "How to interpret --bytes, either 'image', 'skp', or 'api'.");
mtklein 2016/01/20 14:49:06 We may want to make this type, not mode, so that w
kjlubick 2016/01/20 19:21:58 Done.
+DEFINE_string(dump, "", "If not empty, dump 'image' or 'skp' modes as a PNG with this name.");
+
+void printUsage(char*);
mtklein 2016/01/20 14:49:06 It is a good habit to get into make functions (rea
mtklein 2016/01/20 14:49:06 It's another good habit to take your arguments wit
kjlubick 2016/01/20 19:21:58 Done.
+int runSingleTest(SkData*);
mtklein 2016/01/20 14:49:06 Let's make these more symmetric: static int fuzz_
kjlubick 2016/01/20 19:21:58 Done.
+int decodeImage(SkData*);
+int decodeSkp();
+
int main(int argc, char** argv) {
SkCommandLineFlags::Parse(argc, argv);
- if (FLAGS_bytes.isEmpty()) {
mtklein 2016/01/20 14:49:06 I think you need to rebase your patch. Are you in
kjlubick 2016/01/20 19:21:58 Whoops, just needed a rebase.
- SkDebugf("Usage: %s -b <path/to/fuzzed.data> [-m pattern]\n", argv[0]);
+ if (FLAGS_bytes.isEmpty() || FLAGS_mode.isEmpty()) {
+ printUsage(argv[0]);
mtklein 2016/01/20 14:49:06 You might consider writing this as: static int us
scroggo 2016/01/20 18:46:19 SkCommandLineFlags has a "usage" string, but it on
kjlubick 2016/01/20 19:21:57 That would be nice.
kjlubick 2016/01/20 19:21:58 Done.
return 1;
}
+
+ if (0 == strcmp(FLAGS_mode[0], "skp")) {
+ return decodeSkp();
+ }
+
SkAutoTUnref<SkData> bytes(SkData::NewFromFileName(FLAGS_bytes[0]));
+ if (!bytes) {
+ SkDebugf("Could not read %s\n", FLAGS_bytes[0]);
+ return 2;
+ }
+ if (0 == strcmp(FLAGS_mode[0], "api")) {
mtklein 2016/01/20 14:49:06 This is fine, but we probably don't need to be thi
kjlubick 2016/01/20 19:21:58 Done, although I'm not sure what the c is for.
+ return runSingleTest(bytes);
+ } else if (0 == strcmp(FLAGS_mode[0], "image")) {
+ return decodeImage(bytes);
+ }
+ printUsage(argv[0]);
+ return 1;
+}
+void printUsage(char* name) {
+ SkDebugf("Usage: %s --mode <mode> -b <path/to/file> [-m pattern]\n", name);
mtklein 2016/01/20 14:49:07 It seems like this one would be more useful if def
kjlubick 2016/01/20 19:21:58 Done.
+}
+
+int runSingleTest(SkData* bytes) {
for (auto r = SkTRegistry<Fuzzable>::Head(); r; r = r->next()) {
auto fuzzable = r->factory();
if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, fuzzable.name)) {
SkDebugf("Fuzzing %s...\n", fuzzable.name);
Fuzz fuzz(bytes);
fuzzable.fn(&fuzz);
+ return 0;
}
}
return 0;
mtklein 2016/01/20 14:49:06 1?
kjlubick 2016/01/20 19:21:58 Done.
}
+int decodeImage(SkData* bytes) {
+ SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(bytes));
mtklein 2016/01/20 14:49:06 This can't really be the easiest way to use SkCode
scroggo 2016/01/20 18:46:19 This looks about right. It's complicated in part b
kjlubick 2016/01/20 19:21:58 I went over it with scroggo@ yesterday, and this i
+ if (nullptr == codec.get()) {
+ SkDebugf("Couldn't create codec.");
+ return 3;
+ }
+
+ SkImageInfo decodeInfo = codec->getInfo();
+ // Construct a color table for the decode if necessary
+ SkAutoTUnref<SkColorTable> colorTable(nullptr);
+ SkPMColor* colorPtr = nullptr;
+ int* colorCountPtr = nullptr;
+ int maxColors = 256;
+ if (kIndex_8_SkColorType == decodeInfo.colorType()) {
+ SkPMColor colors[256];
+ colorTable.reset(new SkColorTable(colors, maxColors));
+ colorPtr = const_cast<SkPMColor*>(colorTable->readColors());
+ colorCountPtr = &maxColors;
+ }
+
+ SkBitmap bitmap;
+ SkMallocPixelRef::ZeroedPRFactory zeroFactory;
+ SkCodec::Options options;
+ options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
+
+ if (!bitmap.tryAllocPixels(decodeInfo, &zeroFactory, nullptr)) {
+ SkDebugf("Could not allocate memory. Image might be too large (%d x %d)",
+ decodeInfo.width(), decodeInfo.height());
+ return 4;
+ }
+
+ switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), &options,
+ colorPtr, colorCountPtr)) {
+ case SkCodec::kSuccess:
+ SkDebugf("Success!\n");
+ break;
+ case SkCodec::kIncompleteInput:
+ SkDebugf("Partial Success\n");
+ break;
+ case SkCodec::kInvalidConversion:
+ SkDebugf("Incompatible colortype conversion");
+ return 5;
+ default:
+ // Everything else is considered a failure.
+ SkDebugf("Couldn't getPixels.");
+ return 6;
+ }
+
+
+ if (!FLAGS_dump.isEmpty()) {
+ SkImageEncoder::EncodeFile(FLAGS_dump[0], bitmap, SkImageEncoder::kPNG_Type, 100);
+ SkDebugf("Dumped to %s\n", FLAGS_dump[0]);
+ }
+ return 0;
+}
+
+static const SkRect kSKPViewport = {0,0, 1000,1000};
+
+int decodeSkp() {
+ SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(FLAGS_bytes[0]));
+ if (!stream) {
+ SkDebugf("Couldn't read %s.", FLAGS_bytes[0]);
+ return 2;
+ }
+ SkDebugf("Decoding\n");
+ SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream));
+ if (!pic) {
+ SkDebugf("Couldn't decode as a picture.\n");
+ return 3;
+ }
+ SkDebugf("Rendering\n");
+ SkBitmap bitmap;
+ if (!FLAGS_dump.isEmpty()) {
+ SkIRect size = pic->cullRect().roundOut();
+ bitmap.allocN32Pixels(size.width(), size.height());
+ }
+ SkCanvas canvas(bitmap);
+ canvas.clipRect(kSKPViewport);
mtklein 2016/01/20 14:49:06 Let's not do this? If we're allocating space for
kjlubick 2016/01/20 19:21:58 Done.
+ canvas.drawPicture(pic);
+ SkDebugf("Decoded and rendered an SkPicture!\n");
+ if (!FLAGS_dump.isEmpty()) {
+ SkImageEncoder::EncodeFile(FLAGS_dump[0], bitmap, SkImageEncoder::kPNG_Type, 100);
mtklein 2016/01/20 14:49:06 Seems like we've got a bunch of common logic for .
kjlubick 2016/01/20 19:21:57 Deduped.
+ SkDebugf("Dumped to %s\n", FLAGS_dump[0]);
+ }
+ return 0;
+}
Fuzz::Fuzz(SkData* bytes) : fBytes(SkSafeRef(bytes)), fNextByte(0) {}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698