Minor change to AP generation logic

Current behavior:
    Our CPVT_GenerateAP::Generate*AP() functions do not get called as
    long as the annotation dictionary has an "AP" entry.

Problem:
    We always need the "N" entry in AP dictionary to display an
    annotation. Even though the spec requires "AP" dictionary to have an
    "N" entry for normal mode appearance, in case of a malformed pdf
    with "AP" but without "N" in "AP", we won't be able to display the
    annotation at all.

Fix:
    Always check if "AP" has "N" entry to decide whether AP needs to be
    generated. If not, then we still need to generate AP, and add to the
    AP dictionary under the key "N".

Bug=pdfium:778
Change-Id: Icf0c6a681b3c8c22b0b67bf8d16ce6fefdc2c45b
Reviewed-on: https://pdfium-review.googlesource.com/6692
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Jane Liu <janeliulwq@google.com>
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index eab6cd0..e0f073f 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -34,9 +34,10 @@
 }
 
 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) {
-  // If AP dictionary exists, we use the appearance defined in the
-  // existing AP dictionary.
-  if (pAnnotDict->KeyExist("AP"))
+  // If AP dictionary exists and defines an appearance for normal mode, we use
+  // the appearance defined in the existing AP dictionary.
+  CPDF_Dictionary* pAP = pAnnotDict->GetDictFor("AP");
+  if (pAP && pAP->GetDictFor("N"))
     return false;
 
   return !CPDF_Annot::IsAnnotationHidden(pAnnotDict);
diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp
index d542e8c..f76f58a 100644
--- a/core/fpdfdoc/cpvt_generateap.cpp
+++ b/core/fpdfdoc/cpvt_generateap.cpp
@@ -602,7 +602,10 @@
   CPDF_Stream* pNormalStream = pDoc->NewIndirect<CPDF_Stream>();
   pNormalStream->SetData(sAppStream.GetBuffer(), sAppStream.GetSize());
 
-  CPDF_Dictionary* pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP");
+  CPDF_Dictionary* pAPDict = pAnnotDict->GetDictFor("AP");
+  if (!pAPDict)
+    pAPDict = pAnnotDict->SetNewFor<CPDF_Dictionary>("AP");
+
   pAPDict->SetNewFor<CPDF_Reference>("N", pDoc, pNormalStream->GetObjNum());
 
   CPDF_Dictionary* pStreamDict = pNormalStream->GetDict();
diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp
index 85f9b68..b7dee88 100644
--- a/fpdfsdk/fpdfannot_embeddertest.cpp
+++ b/fpdfsdk/fpdfannot_embeddertest.cpp
@@ -13,6 +13,23 @@
 
 class FPDFAnnotEmbeddertest : public EmbedderTest, public TestSaver {};
 
+TEST_F(FPDFAnnotEmbeddertest, RenderAnnotWithOnlyRolloverAP) {
+  // Open a file with one annotation and load its first page.
+  ASSERT_TRUE(OpenDocument("annotation_highlight_rollover_ap.pdf"));
+  FPDF_PAGE page = FPDF_LoadPage(document(), 0);
+  ASSERT_TRUE(page);
+
+  // This annotation has a malformed appearance stream, which does not have its
+  // normal appearance defined, only its rollover appearance. In this case, its
+  // normal appearance should be generated, allowing the highlight annotation to
+  // still display.
+  FPDF_BITMAP bitmap = RenderPageWithFlags(page, FPDF_ANNOT);
+  CompareBitmap(bitmap, 612, 792, "dc98f06da047bd8aabfa99562d2cbd1e");
+  FPDFBitmap_Destroy(bitmap);
+
+  UnloadPage(page);
+}
+
 TEST_F(FPDFAnnotEmbeddertest, ExtractHighlightLongContent) {
   // Open a file with one annotation and load its first page.
   ASSERT_TRUE(OpenDocument("annotation_highlight_long_content.pdf"));
diff --git a/testing/embedder_test.cpp b/testing/embedder_test.cpp
index f818091..7e34260 100644
--- a/testing/embedder_test.cpp
+++ b/testing/embedder_test.cpp
@@ -266,7 +266,7 @@
   FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
   FPDFBitmap_FillRect(bitmap, 0, 0, width, height, fill_color);
   FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, flags);
-  FPDF_FFLDraw(form_handle_, bitmap, page, 0, 0, width, height, 0, 0);
+  FPDF_FFLDraw(form_handle_, bitmap, page, 0, 0, width, height, 0, flags);
   return bitmap;
 }
 
diff --git a/testing/resources/annotation_highlight_rollover_ap.in b/testing/resources/annotation_highlight_rollover_ap.in
new file mode 100644
index 0000000..426ed88
--- /dev/null
+++ b/testing/resources/annotation_highlight_rollover_ap.in
@@ -0,0 +1,86 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 20 0 R
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Highlight
+  /Rect [ 75 681 512 690 ]
+  /NM (Annot-1)
+  /F 4
+  /QuadPoints [ 75 688 512 688 75 679 512 679 ]
+  /C [ 0.0001108646 0.001760244 0.9982184 ]
+  /Contents ()
+  /AP <<
+    /R 5 0 R
+  >>
+>>
+endobj
+
+{{object 5 0}} <<
+  /BBox [
+    67.7299
+    704.296
+    136.325
+    721.292
+  ]
+  /FormType 1
+  /Matrix [
+    1.0
+    0.0
+    0.0
+    1.0
+    -67.7299
+    -704.296
+  ]
+  /Resources <<
+    /ProcSet [
+      /PDF
+    ]
+  >>
+  /Subtype /Form
+  /Type /XObject
+  /Length 165
+>>
+stream
+1 0.819611 0 rg
+0.9997 w
+72 704.7961 m
+68.2298 708.5663 68.2298 717.0216 72 720.7918 c
+132.0551 720.7918 l
+135.8253 717.0216 135.8253 708.5663 132.0551 704.7961 c
+f
+endstream
+>>
+endobj
+
+{{xref}}
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/annotation_highlight_rollover_ap.pdf b/testing/resources/annotation_highlight_rollover_ap.pdf
new file mode 100644
index 0000000..1763b2c
--- /dev/null
+++ b/testing/resources/annotation_highlight_rollover_ap.pdf
@@ -0,0 +1,95 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /OpenAction 20 0 R
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [
+    3 0 R
+  ]
+>>
+endobj
+% Page number 0.
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 612 792]
+  /Annots [
+    4 0 R
+  ]
+  /Tabs /R
+>>
+endobj
+
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Highlight
+  /Rect [ 75 681 512 690 ]
+  /NM (Annot-1)
+  /F 4
+  /QuadPoints [ 75 688 512 688 75 679 512 679 ]
+  /C [ 0.0001108646 0.001760244 0.9982184 ]
+  /Contents ()
+  /AP <<
+    /R 5 0 R
+  >>
+>>
+endobj
+
+5 0 obj <<
+  /BBox [
+    67.7299
+    704.296
+    136.325
+    721.292
+  ]
+  /FormType 1
+  /Matrix [
+    1.0
+    0.0
+    0.0
+    1.0
+    -67.7299
+    -704.296
+  ]
+  /Resources <<
+    /ProcSet [
+      /PDF
+    ]
+  >>
+  /Subtype /Form
+  /Type /XObject
+  /Length 165
+>>
+stream
+1 0.819611 0 rg
+0.9997 w
+72 704.7961 m
+68.2298 708.5663 68.2298 717.0216 72 720.7918 c
+132.0551 720.7918 l
+135.8253 717.0216 135.8253 708.5663 132.0551 704.7961 c
+f
+endstream
+>>
+endobj
+
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000089 00000 n 
+0000000177 00000 n 
+0000000292 00000 n 
+0000000535 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+993
+%%EOF