Add constants for PDF 1.7 spec, table 8.15.

BUG=pdfium:1049

Change-Id: I09fb1c34b8f08ce5c5b5f86e7fe64dfd11ed770d
Reviewed-on: https://pdfium-review.googlesource.com/c/49571
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/constants/BUILD.gn b/constants/BUILD.gn
index 25a574e..cdfd665 100644
--- a/constants/BUILD.gn
+++ b/constants/BUILD.gn
@@ -7,6 +7,7 @@
 
 jumbo_source_set("constants") {
   sources = [
+    "annotation_common.h",
     "form_flags.h",
     "page_object.h",
     "stream_dict_common.h",
diff --git a/constants/annotation_common.h b/constants/annotation_common.h
new file mode 100644
index 0000000..8973360
--- /dev/null
+++ b/constants/annotation_common.h
@@ -0,0 +1,30 @@
+// Copyright 2019 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONSTANTS_ANNOTATION_COMMON_H_
+#define CONSTANTS_ANNOTATION_COMMON_H_
+
+namespace pdfium {
+namespace annotation {
+
+// PDF 1.7 spec, table 8.15.
+// Entries common to all annotation dictionaries.
+
+constexpr char kType[] = "Type";
+constexpr char kSubtype[] = "Subtype";
+constexpr char kRect[] = "Rect";
+constexpr char kContents[] = "Contents";
+constexpr char kP[] = "P";
+constexpr char kNM[] = "NM";
+constexpr char kM[] = "M";
+constexpr char kF[] = "F";
+constexpr char kAP[] = "AP";
+constexpr char kAS[] = "AS";
+constexpr char kBorder[] = "Border";
+constexpr char kC[] = "C";
+
+}  // namespace annotation
+}  // namespace pdfium
+
+#endif  // CONSTANTS_ANNOTATION_COMMON_H_
diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp
index 7e2aea3..1976ebe 100644
--- a/core/fpdfdoc/cpdf_annot.cpp
+++ b/core/fpdfdoc/cpdf_annot.cpp
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <utility>
 
+#include "constants/annotation_common.h"
 #include "core/fpdfapi/page/cpdf_form.h"
 #include "core/fpdfapi/page/cpdf_page.h"
 #include "core/fpdfapi/parser/cpdf_array.h"
@@ -37,7 +38,7 @@
 bool ShouldGenerateAPForAnnotation(CPDF_Dictionary* pAnnotDict) {
   // 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");
+  CPDF_Dictionary* pAP = pAnnotDict->GetDictFor(pdfium::annotation::kAP);
   if (pAP && pAP->GetDictFor("N"))
     return false;
 
@@ -64,7 +65,7 @@
 CPDF_Stream* GetAnnotAPInternal(CPDF_Dictionary* pAnnotDict,
                                 CPDF_Annot::AppearanceMode eMode,
                                 bool bFallbackToNormal) {
-  CPDF_Dictionary* pAP = pAnnotDict->GetDictFor("AP");
+  CPDF_Dictionary* pAP = pAnnotDict->GetDictFor(pdfium::annotation::kAP);
   if (!pAP)
     return nullptr;
 
@@ -86,7 +87,7 @@
   if (!pDict)
     return nullptr;
 
-  ByteString as = pAnnotDict->GetStringFor("AS");
+  ByteString as = pAnnotDict->GetStringFor(pdfium::annotation::kAS);
   if (as.IsEmpty()) {
     ByteString value = pAnnotDict->GetStringFor("V");
     if (value.IsEmpty()) {
@@ -116,7 +117,8 @@
 }
 
 void CPDF_Annot::Init() {
-  m_nSubtype = StringToAnnotSubtype(m_pAnnotDict->GetStringFor("Subtype"));
+  m_nSubtype = StringToAnnotSubtype(
+      m_pAnnotDict->GetStringFor(pdfium::annotation::kSubtype));
   m_bIsTextMarkupAnnotation = IsTextMarkupAnnotation(m_nSubtype);
   m_bHasGeneratedAP =
       m_pAnnotDict->GetBooleanFor(kPDFiumKey_HasGeneratedAP, false);
@@ -162,7 +164,7 @@
   if (bShouldUseQuadPointsCoords)
     return BoundingRectFromQuadPoints(m_pAnnotDict.Get());
 
-  return m_pAnnotDict->GetRectFor("Rect");
+  return m_pAnnotDict->GetRectFor(pdfium::annotation::kRect);
 }
 
 CFX_FloatRect CPDF_Annot::GetRect() const {
@@ -175,7 +177,7 @@
 }
 
 uint32_t CPDF_Annot::GetFlags() const {
-  return m_pAnnotDict->GetIntegerFor("F");
+  return m_pAnnotDict->GetIntegerFor(pdfium::annotation::kF);
 }
 
 CPDF_Stream* GetAnnotAP(CPDF_Dictionary* pAnnotDict,
@@ -257,7 +259,8 @@
 
 // static
 bool CPDF_Annot::IsAnnotationHidden(CPDF_Dictionary* pAnnotDict) {
-  return !!(pAnnotDict->GetIntegerFor("F") & ANNOTFLAG_HIDDEN);
+  return !!(pAnnotDict->GetIntegerFor(pdfium::annotation::kF) &
+            ANNOTFLAG_HIDDEN);
 }
 
 // static
@@ -456,7 +459,8 @@
   float width;
   CPDF_Array* pDashArray = nullptr;
   if (!pBS) {
-    CPDF_Array* pBorderArray = m_pAnnotDict->GetArrayFor("Border");
+    CPDF_Array* pBorderArray =
+        m_pAnnotDict->GetArrayFor(pdfium::annotation::kBorder);
     style_char = 'S';
     if (pBorderArray) {
       width = pBorderArray->GetNumberAt(2);
@@ -490,7 +494,7 @@
   if (width <= 0) {
     return;
   }
-  CPDF_Array* pColor = m_pAnnotDict->GetArrayFor("C");
+  CPDF_Array* pColor = m_pAnnotDict->GetArrayFor(pdfium::annotation::kC);
   uint32_t argb = 0xff000000;
   if (pColor) {
     int R = (int32_t)(pColor->GetNumberAt(0) * 255);
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index 87eac73..e66b9e4 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -134,6 +134,7 @@
   ]
   deps = [
     ":fpdfsdk",
+    "../constants",
     "../core/fpdfapi/font",
     "../core/fpdfapi/page",
     "../core/fpdfapi/parser",
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 035ee1b..8ae6d00 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "constants/annotation_common.h"
 #include "core/fxcrt/fx_system.h"
 #include "public/cpp/fpdf_scopers.h"
 #include "public/fpdf_annot.h"
@@ -17,8 +18,6 @@
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-static constexpr char kContentsKey[] = "Contents";
-
 class FPDFAnnotEmbedderTest : public EmbedderTest {};
 
 std::wstring BufferToWString(const std::vector<char>& buf) {
@@ -134,13 +133,16 @@
     EXPECT_STREQ(L"Jae Hyun Park", BufferToWString(buf).c_str());
 
     // Check that the content is correct.
-    EXPECT_EQ(FPDF_OBJECT_STRING,
-              FPDFAnnot_GetValueType(annot.get(), kContentsKey));
-    len = FPDFAnnot_GetStringValue(annot.get(), kContentsKey, nullptr, 0);
+    EXPECT_EQ(
+        FPDF_OBJECT_STRING,
+        FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kContents));
+    len = FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kContents,
+                                   nullptr, 0);
     buf.clear();
     buf.resize(len);
-    EXPECT_EQ(2690u, FPDFAnnot_GetStringValue(annot.get(), kContentsKey,
-                                              buf.data(), len));
+    EXPECT_EQ(2690u,
+              FPDFAnnot_GetStringValue(
+                  annot.get(), pdfium::annotation::kContents, buf.data(), len));
     const wchar_t contents[] =
         L"This is a note for that highlight annotation. Very long highlight "
         "annotation. Long long long Long long longLong long longLong long "
@@ -203,8 +205,8 @@
     EXPECT_EQ(76u, A);
 
     // Check that there is no content.
-    EXPECT_EQ(2u,
-              FPDFAnnot_GetStringValue(annot.get(), kContentsKey, nullptr, 0));
+    EXPECT_EQ(2u, FPDFAnnot_GetStringValue(
+                      annot.get(), pdfium::annotation::kContents, nullptr, 0));
 
     // Check that the rectange coordinates are correct.
     // Note that upon rendering, the rectangle coordinates will be adjusted.
@@ -306,14 +308,15 @@
         L"Hello! This is a customized content.";
     std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
         GetFPDFWideString(kContents);
-    ASSERT_TRUE(
-        FPDFAnnot_SetStringValue(annot.get(), kContentsKey, text.get()));
+    ASSERT_TRUE(FPDFAnnot_SetStringValue(
+        annot.get(), pdfium::annotation::kContents, text.get()));
     // Check that the content has been set correctly.
-    unsigned long len =
-        FPDFAnnot_GetStringValue(annot.get(), kContentsKey, nullptr, 0);
+    unsigned long len = FPDFAnnot_GetStringValue(
+        annot.get(), pdfium::annotation::kContents, nullptr, 0);
     std::vector<char> buf(len);
-    EXPECT_EQ(74u, FPDFAnnot_GetStringValue(annot.get(), kContentsKey,
-                                            buf.data(), len));
+    EXPECT_EQ(74u,
+              FPDFAnnot_GetStringValue(
+                  annot.get(), pdfium::annotation::kContents, buf.data(), len));
     EXPECT_STREQ(kContents, BufferToWString(buf).c_str());
   }
   UnloadPage(page);
@@ -1051,7 +1054,6 @@
   FPDF_PAGE page = LoadPage(0);
   ASSERT_TRUE(page);
 
-  static constexpr char kDateKey[] = "M";
   static constexpr wchar_t kNewDate[] = L"D:201706282359Z00'00'";
 
   {
@@ -1063,11 +1065,11 @@
     EXPECT_FALSE(FPDFAnnot_HasKey(annot.get(), "none"));
 
     // Check that the string value of a non-string dictionary entry is empty.
-    static constexpr char kApKey[] = "AP";
-    EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), kApKey));
+    EXPECT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kAP));
     EXPECT_EQ(FPDF_OBJECT_REFERENCE,
-              FPDFAnnot_GetValueType(annot.get(), kApKey));
-    EXPECT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), kApKey, nullptr, 0));
+              FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kAP));
+    EXPECT_EQ(2u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kAP,
+                                           nullptr, 0));
 
     // Check that the string value of the hash is correct.
     static constexpr char kHashKey[] = "AAPL:Hash";
@@ -1082,17 +1084,19 @@
 
     // Check that the string value of the modified date is correct.
     EXPECT_EQ(FPDF_OBJECT_NAME, FPDFAnnot_GetValueType(annot.get(), kHashKey));
-    len = FPDFAnnot_GetStringValue(annot.get(), kDateKey, nullptr, 0);
+    len = FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM, nullptr,
+                                   0);
     buf.clear();
     buf.resize(len);
-    EXPECT_EQ(44u,
-              FPDFAnnot_GetStringValue(annot.get(), kDateKey, buf.data(), len));
+    EXPECT_EQ(44u, FPDFAnnot_GetStringValue(annot.get(), pdfium::annotation::kM,
+                                            buf.data(), len));
     EXPECT_STREQ(L"D:201706071721Z00'00'", BufferToWString(buf).c_str());
 
     // Update the date entry for the annotation.
     std::unique_ptr<unsigned short, pdfium::FreeDeleter> text =
         GetFPDFWideString(kNewDate);
-    EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), kDateKey, text.get()));
+    EXPECT_TRUE(FPDFAnnot_SetStringValue(annot.get(), pdfium::annotation::kM,
+                                         text.get()));
   }
 
   // Save the document, closing the page and document.
@@ -1116,12 +1120,13 @@
 
     // Check that the string value of the modified date is the newly-set value.
     EXPECT_EQ(FPDF_OBJECT_STRING,
-              FPDFAnnot_GetValueType(new_annot.get(), kDateKey));
-    unsigned long len =
-        FPDFAnnot_GetStringValue(new_annot.get(), kDateKey, nullptr, 0);
+              FPDFAnnot_GetValueType(new_annot.get(), pdfium::annotation::kM));
+    unsigned long len = FPDFAnnot_GetStringValue(
+        new_annot.get(), pdfium::annotation::kM, nullptr, 0);
     std::vector<char> buf(len);
-    EXPECT_EQ(44u, FPDFAnnot_GetStringValue(new_annot.get(), kDateKey,
-                                            buf.data(), len));
+    EXPECT_EQ(44u,
+              FPDFAnnot_GetStringValue(new_annot.get(), pdfium::annotation::kM,
+                                       buf.data(), len));
     EXPECT_STREQ(kNewDate, BufferToWString(buf).c_str());
   }
 
@@ -1359,11 +1364,10 @@
 
     // Attempting to retrieve |annot|'s parent dictionary as an annotation
     // would fail, since its parent is not an annotation.
-    static constexpr char kPKey[] = "P";
-    ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), kPKey));
+    ASSERT_TRUE(FPDFAnnot_HasKey(annot.get(), pdfium::annotation::kP));
     EXPECT_EQ(FPDF_OBJECT_REFERENCE,
-              FPDFAnnot_GetValueType(annot.get(), kPKey));
-    EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), kPKey));
+              FPDFAnnot_GetValueType(annot.get(), pdfium::annotation::kP));
+    EXPECT_FALSE(FPDFAnnot_GetLinkedAnnot(annot.get(), pdfium::annotation::kP));
   }
 
   UnloadPage(page);