Add FPDFAnnot_GetFormFieldAlternateName() API

This is similar to FPDFAnnot_GetFormFieldName() and allows getting the
alternate name. Such names are used e.g. for accessibility purposes.

Bug: pdfium:1892
Change-Id: I95dc771af64d6091b742f1da21e50a99327e015b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/98210
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Miklos V <miklos.vajna@collabora.com>
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp
index 28661ec..9861b81 100644
--- a/fpdfsdk/fpdf_annot.cpp
+++ b/fpdfsdk/fpdf_annot.cpp
@@ -1264,6 +1264,19 @@
 }
 
 FPDF_EXPORT unsigned long FPDF_CALLCONV
+FPDFAnnot_GetFormFieldAlternateName(FPDF_FORMHANDLE hHandle,
+                                    FPDF_ANNOTATION annot,
+                                    FPDF_WCHAR* buffer,
+                                    unsigned long buflen) {
+  const CPDF_FormField* pFormField = GetFormField(hHandle, annot);
+  if (!pFormField)
+    return 0;
+
+  return Utf16EncodeMaybeCopyAndReturnLength(pFormField->GetAlternateName(),
+                                             buffer, buflen);
+}
+
+FPDF_EXPORT unsigned long FPDF_CALLCONV
 FPDFAnnot_GetFormFieldValue(FPDF_FORMHANDLE hHandle,
                             FPDF_ANNOTATION annot,
                             FPDF_WCHAR* buffer,
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 0328f39..8f3cf43 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -3650,6 +3650,35 @@
   UnloadPage(page);
 }
 
+TEST_F(FPDFAnnotEmbedderTest, FormFieldAlternateName) {
+  ASSERT_TRUE(OpenDocument("click_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+  EXPECT_EQ(8, FPDFPage_GetAnnotCount(page));
+
+  {
+    ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, 0));
+    ASSERT_TRUE(annot);
+
+    // FPDFAnnot_GetFormFieldAlternateName() positive testing.
+    unsigned long length_bytes = FPDFAnnot_GetFormFieldAlternateName(
+        form_handle(), annot.get(), nullptr, 0);
+    ASSERT_EQ(34u, length_bytes);
+    std::vector<FPDF_WCHAR> buf = GetFPDFWideStringBuffer(length_bytes);
+    EXPECT_EQ(34u, FPDFAnnot_GetFormFieldAlternateName(
+                       form_handle(), annot.get(), buf.data(), length_bytes));
+    EXPECT_EQ(L"readOnlyCheckbox", GetPlatformWString(buf.data()));
+
+    // FPDFAnnot_GetFormFieldAlternateName() negative testing.
+    EXPECT_EQ(0u, FPDFAnnot_GetFormFieldAlternateName(form_handle(), nullptr,
+                                                      nullptr, 0));
+    EXPECT_EQ(0u, FPDFAnnot_GetFormFieldAlternateName(nullptr, annot.get(),
+                                                      nullptr, 0));
+  }
+
+  UnloadPage(page);
+}
+
 // Due to https://crbug.com/pdfium/570, the AnnotationBorder test above cannot
 // actually render the line annotations inside line_annot.pdf. For now, use a
 // square annotation in annots.pdf for testing.
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index 7951525..0f656ae 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -55,6 +55,7 @@
     CHK(FPDFAnnot_GetFormAdditionalActionJavaScript);
     CHK(FPDFAnnot_GetFormControlCount);
     CHK(FPDFAnnot_GetFormControlIndex);
+    CHK(FPDFAnnot_GetFormFieldAlternateName);
     CHK(FPDFAnnot_GetFormFieldAtPoint);
     CHK(FPDFAnnot_GetFormFieldExportValue);
     CHK(FPDFAnnot_GetFormFieldFlags);
diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h
index 0c0302c..333a6b2 100644
--- a/public/fpdf_annot.h
+++ b/public/fpdf_annot.h
@@ -722,6 +722,26 @@
                            unsigned long buflen);
 
 // Experimental API.
+// Gets the alternate name of |annot|, which is an interactive form annotation.
+// |buffer| is only modified if |buflen| is longer than the length of contents.
+// In case of error, nothing will be added to |buffer| and the return value will
+// be 0. Note that return value of empty string is 2 for "\0\0".
+//
+//    hHandle     -   handle to the form fill module, returned by
+//                    FPDFDOC_InitFormFillEnvironment().
+//    annot       -   handle to an interactive form annotation.
+//    buffer      -   buffer for holding the alternate name string, encoded in
+//                    UTF-16LE.
+//    buflen      -   length of the buffer in bytes.
+//
+// Returns the length of the string value in bytes.
+FPDF_EXPORT unsigned long FPDF_CALLCONV
+FPDFAnnot_GetFormFieldAlternateName(FPDF_FORMHANDLE hHandle,
+                                    FPDF_ANNOTATION annot,
+                                    FPDF_WCHAR* buffer,
+                                    unsigned long buflen);
+
+// Experimental API.
 // Gets the form field type of |annot|, which is an interactive form annotation.
 //
 //    hHandle     -   handle to the form fill module, returned by