Allow update of kReadOnly widget flag from JavaScript

Test: confirm the example in the bug is not editable.
Bug: pdfium:1685
Change-Id: Icc52e3aa7dc69fd6feacc756a4134d44bb6f2c49
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/81190
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp
index 40f52aa..0391657 100644
--- a/core/fpdfdoc/cpdf_formfield.cpp
+++ b/core/fpdfdoc/cpdf_formfield.cpp
@@ -281,6 +281,11 @@
   return pObj ? pObj->GetInteger() : 0;
 }
 
+void CPDF_FormField::SetFieldFlags(uint32_t dwFlags) {
+  m_pDict->SetNewFor<CPDF_Number>(pdfium::form_fields::kFf,
+                                  static_cast<int>(dwFlags));
+}
+
 ByteString CPDF_FormField::GetDefaultStyle() const {
   const CPDF_Object* pObj = GetFieldAttr(m_pDict.Get(), "DS");
   return pObj ? pObj->GetString() : ByteString();
diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h
index 37a52cf..188477a 100644
--- a/core/fpdfdoc/cpdf_formfield.h
+++ b/core/fpdfdoc/cpdf_formfield.h
@@ -98,6 +98,7 @@
   WideString GetMappingName() const;
 
   uint32_t GetFieldFlags() const;
+  void SetFieldFlags(uint32_t dwFlags);
   ByteString GetDefaultStyle() const;
 
   bool IsRequired() const { return m_bRequired; }
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index 096d2d4..b1ac511 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -1660,11 +1660,21 @@
 
 CJS_Result CJS_Field::set_readonly(CJS_Runtime* pRuntime,
                                    v8::Local<v8::Value> vp) {
-  std::vector<CPDF_FormField*> FieldArray = GetFormFields();
-  if (FieldArray.empty())
+  CPDF_FormField* pFormField = GetFirstFormField();
+  if (!pFormField)
     return CJS_Result::Failure(JSMessage::kBadObjectError);
+
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
+
+  const bool bReadOnly = pRuntime->ToBoolean(vp);
+  const uint32_t dwFlags = pFormField->GetFieldFlags();
+  const uint32_t dwNewFlags = bReadOnly
+                                  ? (dwFlags | pdfium::form_flags::kReadOnly)
+                                  : (dwFlags & ~pdfium::form_flags::kReadOnly);
+  if (dwNewFlags != dwFlags)
+    pFormField->SetFieldFlags(dwNewFlags);
+
   return CJS_Result::Success();
 }
 
diff --git a/testing/resources/javascript/field_properties.in b/testing/resources/javascript/field_properties.in
index e498547..1961f6a 100644
--- a/testing/resources/javascript/field_properties.in
+++ b/testing/resources/javascript/field_properties.in
@@ -70,7 +70,7 @@
     testROProperty(field, "page", 0);
     testRIProperty(field, "password", false, 42);
     testRWProperty(field, "print", true, false);
-    testRIProperty(field, "readonly", false, true);
+    testRWProperty(field, "readonly", false, true);
     testROProperty(field, "rect", [200,221,220,201]);
     // testROProperty(field, "required", "clams");
     testRIProperty(field, "richText", false, true);
diff --git a/testing/resources/javascript/field_properties_expected.txt b/testing/resources/javascript/field_properties_expected.txt
index 590fc65..8670196 100644
--- a/testing/resources/javascript/field_properties_expected.txt
+++ b/testing/resources/javascript/field_properties_expected.txt
@@ -51,7 +51,7 @@
 Alert: PASS: print = true
 Alert: PASS: print = false
 Alert: PASS: readonly = false
-Alert: PASS: readonly = false
+Alert: PASS: readonly = true
 Alert: PASS: rect = 200,221,220,201
 Alert: PASS: rect threw Field.rect: Incorrect parameter value.
 Alert: PASS: richText = false