diff options
author | halcanary <halcanary@google.com> | 2016-09-09 11:41:59 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-09-09 11:41:59 -0700 |
commit | 57f744e3030fec4d1a2b3e9119011904b149a4da (patch) | |
tree | 62e2dbe5a2550e0fccfcf085663ada6a8a3d8756 | |
parent | 8d914908d8ad37a73c39ba8f7ef298bfee457388 (diff) |
SkPDF/Tests: imporve test coverage.
Also: make sure that all SkPDF unit tests are named SkPDF_* to
make testing changes to SkPDF easier. Other cleanup.
Add test: SkPDF_pdfa_document to verify that flag in public API
works.
SkPDF_JpegIdentification test: test slightly malformed JPEGs to
verify that all code paths work.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2322133003
Review-Url: https://codereview.chromium.org/2322133003
-rw-r--r-- | tests/PDFDeflateWStreamTest.cpp | 5 | ||||
-rw-r--r-- | tests/PDFDocumentTest.cpp | 70 | ||||
-rw-r--r-- | tests/PDFGlyphsToUnicodeTest.cpp | 2 | ||||
-rw-r--r-- | tests/PDFInvalidBitmapTest.cpp | 5 | ||||
-rw-r--r-- | tests/PDFJpegEmbedTest.cpp | 110 | ||||
-rw-r--r-- | tests/PDFPrimitivesTest.cpp | 11 |
6 files changed, 183 insertions, 20 deletions
diff --git a/tests/PDFDeflateWStreamTest.cpp b/tests/PDFDeflateWStreamTest.cpp index 262750876e..eedcaaf0c5 100644 --- a/tests/PDFDeflateWStreamTest.cpp +++ b/tests/PDFDeflateWStreamTest.cpp @@ -101,7 +101,7 @@ SkStreamAsset* stream_inflate(skiatest::Reporter* reporter, SkStream* src) { } } // namespace -DEF_TEST(SkDeflateWStream, r) { +DEF_TEST(SkPDF_DeflateWStream, r) { SkRandom random(123456); for (int i = 0; i < 50; ++i) { uint32_t size = random.nextULessThan(10000); @@ -123,6 +123,7 @@ DEF_TEST(SkDeflateWStream, r) { } j += writeSize; } + REPORTER_ASSERT(r, deflateWStream.bytesWritten() == size); } SkAutoTDelete<SkStreamAsset> compressed( dynamicMemoryWStream.detachAsStream()); @@ -159,4 +160,6 @@ DEF_TEST(SkDeflateWStream, r) { } } } + SkDeflateWStream emptyDeflateWStream(nullptr); + REPORTER_ASSERT(r, !emptyDeflateWStream.writeText("FOO")); } diff --git a/tests/PDFDocumentTest.cpp b/tests/PDFDocumentTest.cpp index b763742b06..c871375117 100644 --- a/tests/PDFDocumentTest.cpp +++ b/tests/PDFDocumentTest.cpp @@ -105,7 +105,7 @@ static void test_close(skiatest::Reporter* reporter) { REPORTER_ASSERT(reporter, stream.bytesWritten() != 0); } -DEF_TEST(document_tests, reporter) { +DEF_TEST(SkPDF_document_tests, reporter) { REQUIRE_PDF_DOCUMENT(document_tests, reporter); test_empty(reporter); test_abort(reporter); @@ -147,8 +147,8 @@ size_t count_bytes(const SkBitmap& bm, bool useDCT) { return stream.bytesWritten(); } -DEF_TEST(document_dct_encoder, r) { - REQUIRE_PDF_DOCUMENT(document_dct_encoder, r); +DEF_TEST(SkPDF_document_dct_encoder, r) { + REQUIRE_PDF_DOCUMENT(SkPDF_document_dct_encoder, r); SkBitmap bm; if (GetResourceAsBitmap("mandrill_64.png", &bm)) { // Lossy encoding works better on photographs. @@ -156,8 +156,8 @@ DEF_TEST(document_dct_encoder, r) { } } -DEF_TEST(document_skbug_4734, r) { - REQUIRE_PDF_DOCUMENT(document_skbug_4734, r); +DEF_TEST(SkPDF_document_skbug_4734, r) { + REQUIRE_PDF_DOCUMENT(SkPDF_document_skbug_4734, r); SkDynamicMemoryWStream stream; sk_sp<SkDocument> doc(SkDocument::MakePDF(&stream)); SkCanvas* canvas = doc->beginPage(64, 64); @@ -167,3 +167,63 @@ DEF_TEST(document_skbug_4734, r) { const char text[] = "HELLO"; canvas->drawText(text, strlen(text), 0, 0, SkPaint()); } + +static bool contains(const uint8_t* result, size_t size, const char expectation[]) { + size_t len = strlen(expectation); + size_t N = 1 + size - len; + for (size_t i = 0; i < N; ++i) { + if (0 == memcmp(result + i, expectation, len)) { + return true; + } + } + return false; +} + +// verify that the PDFA flag does something. +DEF_TEST(SkPDF_pdfa_document, r) { + REQUIRE_PDF_DOCUMENT(SkPDF_pdfa_document, r); + + SkDocument::PDFMetadata pdfMetadata; + pdfMetadata.fTitle = "test document"; + pdfMetadata.fCreation.fEnabled = true; + pdfMetadata.fCreation.fDateTime = {0, 1999, 12, 5, 31, 23, 59, 59}; + + SkDynamicMemoryWStream buffer; + auto doc = SkDocument::MakePDF(&buffer, SK_ScalarDefaultRasterDPI, + pdfMetadata, nullptr, /* pdfa = */ true); + doc->beginPage(64, 64)->drawColor(SK_ColorRED); + doc->close(); + sk_sp<SkData> data(buffer.copyToData()); + buffer.reset(); + static const char* expectations[] = { + "sRGB IEC61966-2.1", + "<dc:title><rdf:Alt><rdf:li xml:lang=\"x-default\">test document", + "<xmp:CreateDate>1999-12-31T23:59:59+00:00</xmp:CreateDate>", + "/Subtype /XML", + "/CreationDate (D:19991231235959+00'00')>>", + }; + for (const char* expectation : expectations) { + if (!contains(data->bytes(), data->size(), expectation)) { + ERRORF(r, "PDFA expectation missing: '%s'.", expectation); + } + } + pdfMetadata.fProducer = "phoney library"; + doc = SkDocument::MakePDF(&buffer, SK_ScalarDefaultRasterDPI, + pdfMetadata, nullptr, /* pdfa = */ true); + doc->beginPage(64, 64)->drawColor(SK_ColorRED); + doc->close(); + data.reset(buffer.copyToData()); + buffer.reset(); + + static const char* moreExpectations[] = { + "/Producer (phoney library)", + "/ProductionLibrary (Skia/PDF m", + "<!-- <skia:ProductionLibrary>Skia/PDF m", + "<pdf:Producer>phoney library</pdf:Producer>", + }; + for (const char* expectation : moreExpectations) { + if (!contains(data->bytes(), data->size(), expectation)) { + ERRORF(r, "PDFA expectation missing: '%s'.", expectation); + } + } +} diff --git a/tests/PDFGlyphsToUnicodeTest.cpp b/tests/PDFGlyphsToUnicodeTest.cpp index 3ba8870774..f65ee3e3c7 100644 --- a/tests/PDFGlyphsToUnicodeTest.cpp +++ b/tests/PDFGlyphsToUnicodeTest.cpp @@ -25,7 +25,7 @@ static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, return memcmp(data->bytes() + offset, buffer, len) == 0; } -DEF_TEST(ToUnicode, reporter) { +DEF_TEST(SkPDF_ToUnicode, reporter) { SkTDArray<SkUnichar> glyphToUnicode; SkTDArray<uint16_t> glyphsInSubset; SkBitSet subset(kMaximumGlyphCount); diff --git a/tests/PDFInvalidBitmapTest.cpp b/tests/PDFInvalidBitmapTest.cpp index c9685f7893..10292bdb5f 100644 --- a/tests/PDFInvalidBitmapTest.cpp +++ b/tests/PDFInvalidBitmapTest.cpp @@ -43,9 +43,12 @@ SkBitmap make_invalid_bitmap(SkColorType colorType) { } // namespace -DEF_TEST(PDFInvalidBitmap, reporter) { +DEF_TEST(SkPDF_InvalidBitmap, reporter) { SkDynamicMemoryWStream stream; sk_sp<SkDocument> document(SkDocument::MakePDF(&stream)); + if (!document) { + return; + } SkCanvas* canvas = document->beginPage(100, 100); canvas->drawBitmap(SkBitmap(), 0, 0); diff --git a/tests/PDFJpegEmbedTest.cpp b/tests/PDFJpegEmbedTest.cpp index b199c80e75..93c204401d 100644 --- a/tests/PDFJpegEmbedTest.cpp +++ b/tests/PDFJpegEmbedTest.cpp @@ -5,10 +5,11 @@ * found in the LICENSE file. */ -#include "SkDocument.h" #include "SkCanvas.h" -#include "SkImageGenerator.h" #include "SkData.h" +#include "SkDocument.h" +#include "SkImageGenerator.h" +#include "SkJpegInfo.h" #include "SkStream.h" #include "Resources.h" @@ -54,8 +55,9 @@ static sk_sp<SkData> load_resource( * directly embedded into the PDF (without re-encoding) when that * makes sense. */ -DEF_TEST(PDFJpegEmbedTest, r) { - const char test[] = "PDFJpegEmbedTest"; +DEF_TEST(SkPDF_JpegEmbedTest, r) { + REQUIRE_PDF_DOCUMENT(SkPDF_JpegEmbedTest, r); + const char test[] = "SkPDF_JpegEmbedTest"; sk_sp<SkData> mandrillData(load_resource(r, test, "mandrill_512_q075.jpg")); sk_sp<SkData> cmykData(load_resource(r, test, "CMYK.jpg")); if (!mandrillData || !cmykData) { @@ -111,9 +113,7 @@ DEF_TEST(PDFJpegEmbedTest, r) { REPORTER_ASSERT(r, !is_subset_of(cmykData.get(), pdfData.get())); } -#include "SkJpegInfo.h" - -DEF_TEST(JpegIdentification, r) { +DEF_TEST(SkPDF_JpegIdentification, r) { static struct { const char* path; bool isJfif; @@ -144,4 +144,100 @@ DEF_TEST(JpegIdentification, r) { INFOF(r, "\nJpegIdentification: %s [%d x %d]\n", kTests[i].path, info.fSize.width(), info.fSize.height()); } + + // Test several malformed jpegs. + SkJFIFInfo info; + { + static const char goodJpeg[] = + "\377\330\377\340\0\20JFIF\0\1\1\0\0\1\0\1\0\0\377\333\0C\0\10\6\6\7" + "\6\5\10\7\7\7\t\t\10\n\14\24\r\14\13\13\14\31\22\23\17\24\35\32\37" + "\36\35\32\34\34 $.' \",#\34\34(7),01444\37'9=82<.342\377\333\0C\1\t" + "\t\t\14\13\14\30\r\r\0302!\34!222222222222222222222222222222222222" + "22222222222222\377\300\0\21\10\2\0\2\0\3\1\"\0\2\21\1\3\21\001"; + size_t goodJpegLength = 177; + auto data = SkData::MakeWithoutCopy(goodJpeg, goodJpegLength); + REPORTER_ASSERT(r, SkIsJFIF(data.get(), &info)); + REPORTER_ASSERT(r, info.fSize == SkISize::Make(512, 512)); + REPORTER_ASSERT(r, info.fType == SkJFIFInfo::kYCbCr); + + // Not long enough to read first (SOI) segment marker. + data = SkData::MakeWithoutCopy(goodJpeg, 1); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + + // Not long enough to read second segment (APP0) marker. + data = SkData::MakeWithoutCopy(goodJpeg, 3); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + + // Not long enough to read second segment's length. + data = SkData::MakeWithoutCopy(goodJpeg, 5); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + + // APP0 segment is truncated. + data = SkData::MakeWithoutCopy(goodJpeg, 7); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + + // Missing SOF segment. + data = SkData::MakeWithoutCopy(goodJpeg, 89); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + } + { + // JFIF tag missing. + static const char jpeg[] = + "\377\330\377\340\0\20JFIX\0\1\1\0\0\1\0\1\0\0\377\333\0C\0\10\6\6\7" + "\6\5\10\7\7\7\t\t\10\n\14\24\r\14\13\13\14\31\22\23\17\24\35\32\37" + "\36\35\32\34\34 $.' \",#\34\34(7),01444\37'9=82<.342\377\333\0C\1\t" + "\t\t\14\13\14\30\r\r\0302!\34!222222222222222222222222222222222222" + "22222222222222\377\300\0\21\10\2\0\2\0\3\1\"\0\2\21\1\3\21\001"; + size_t jpegLength = 177; + auto data = SkData::MakeWithoutCopy(jpeg, jpegLength); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + } + { + // APP0 segment short (byte 6 changed). + static const char jpeg[] = + "\377\330\377\340\0\5JFIF\0\1\1\0\0\1\0\1\0\0\377\333\0C\0\10\6\6\7" + "\6\5\10\7\7\7\t\t\10\n\14\24\r\14\13\13\14\31\22\23\17\24\35\32\37" + "\36\35\32\34\34 $.' \",#\34\34(7),01444\37'9=82<.342\377\333\0C\1\t" + "\t\t\14\13\14\30\r\r\0302!\34!222222222222222222222222222222222222" + "22222222222222\377\300\0\21\10\2\0\2\0\3\1\"\0\2\21\1\3\21\001"; + size_t jpegLength = 177; + auto data = SkData::MakeWithoutCopy(jpeg, jpegLength); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + } + { + // SOF segment short. ('\21' replaced with '\5') + static const char jpeg[] = + "\377\330\377\340\0\20JFIF\0\1\1\0\0\1\0\1\0\0\377\333\0C\0\10\6\6\7" + "\6\5\10\7\7\7\t\t\10\n\14\24\r\14\13\13\14\31\22\23\17\24\35\32\37" + "\36\35\32\34\34 $.' \",#\34\34(7),01444\37'9=82<.342\377\333\0C\1\t" + "\t\t\14\13\14\30\r\r\0302!\34!222222222222222222222222222222222222" + "22222222222222\377\300\0\5\10\2\0\2\0\3\1\"\0\2\21\1\3\21\001"; + size_t jpegLength = 177; + auto data = SkData::MakeWithoutCopy(jpeg, jpegLength); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + } + { + // Unsupported 12-bit components. ('\10' replaced with '\14') + static const char jpeg[] = + "\377\330\377\340\0\20JFIF\0\1\1\0\0\1\0\1\0\0\377\333\0C\0\10\6\6\7" + "\6\5\10\7\7\7\t\t\10\n\14\24\r\14\13\13\14\31\22\23\17\24\35\32\37" + "\36\35\32\34\34 $.' \",#\34\34(7),01444\37'9=82<.342\377\333\0C\1\t" + "\t\t\14\13\14\30\r\r\0302!\34!222222222222222222222222222222222222" + "22222222222222\377\300\0\21\14\2\0\2\0\3\1\"\0\2\21\1\3\21\001"; + size_t jpegLength = 177; + auto data = SkData::MakeWithoutCopy(jpeg, jpegLength); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + } + { + // Two color channels. ('\3' replaced with '\2') + static const char jpeg[] = + "\377\330\377\340\0\20JFIF\0\1\1\0\0\1\0\1\0\0\377\333\0C\0\10\6\6\7" + "\6\5\10\7\7\7\t\t\10\n\14\24\r\14\13\13\14\31\22\23\17\24\35\32\37" + "\36\35\32\34\34 $.' \",#\34\34(7),01444\37'9=82<.342\377\333\0C\1\t" + "\t\t\14\13\14\30\r\r\0302!\34!222222222222222222222222222222222222" + "22222222222222\377\300\0\21\10\2\0\2\0\2\1\"\0\2\21\1\3\21\001"; + size_t jpegLength = 177; + auto data = SkData::MakeWithoutCopy(jpeg, jpegLength); + REPORTER_ASSERT(r, !SkIsJFIF(data.get(), &info)); + } } diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp index 1001b99c47..c719f488d2 100644 --- a/tests/PDFPrimitivesTest.cpp +++ b/tests/PDFPrimitivesTest.cpp @@ -334,7 +334,7 @@ static void TestPDFDict(skiatest::Reporter* reporter) { assert_eq(reporter, result, "<</Type /DType\n/n1 1 0 R>>"); } -DEF_TEST(PDFPrimitives, reporter) { +DEF_TEST(SkPDF_Primitives, reporter) { TestPDFUnion(reporter); TestPDFArray(reporter); TestPDFDict(reporter); @@ -389,7 +389,8 @@ void DummyImageFilter::toString(SkString* str) const { // Check that PDF rendering of image filters successfully falls back to // CPU rasterization. -DEF_TEST(PDFImageFilter, reporter) { +DEF_TEST(SkPDF_ImageFilter, reporter) { + REQUIRE_PDF_DOCUMENT(SkPDF_ImageFilter, reporter); SkDynamicMemoryWStream stream; sk_sp<SkDocument> doc(SkDocument::MakePDF(&stream)); SkCanvas* canvas = doc->beginPage(100.0f, 100.0f); @@ -409,7 +410,7 @@ DEF_TEST(PDFImageFilter, reporter) { // Check that PDF rendering of image filters successfully falls back to // CPU rasterization. -DEF_TEST(PDFFontCanEmbedTypeface, reporter) { +DEF_TEST(SkPDF_FontCanEmbedTypeface, reporter) { SkPDFCanon canon; const char resource[] = "fonts/Roboto2-Regular_NoEmbed.ttf"; @@ -453,7 +454,7 @@ static void check_pdf_scalar_serialization( } // Test SkPDFUtils::AppendScalar for accuracy. -DEF_TEST(PDFPrimitives_Scalar, reporter) { +DEF_TEST(SkPDF_Primitives_Scalar, reporter) { SkRandom random(0x5EED); int iterationCount = 512; while (iterationCount-- > 0) { @@ -474,7 +475,7 @@ DEF_TEST(PDFPrimitives_Scalar, reporter) { } // Test SkPDFUtils:: for accuracy. -DEF_TEST(PDFPrimitives_Color, reporter) { +DEF_TEST(SkPDF_Primitives_Color, reporter) { char buffer[5]; for (int i = 0; i < 256; ++i) { size_t len = SkPDFUtils::ColorToDecimal(i, buffer); |