Make Document's 'info' property readonly

As per the PDF specification in [1], page 103, the
'info' property of the Document object is readonly.

[1] http://partners.adobe.com/public/developer/en/acrobat/sdk/5186AcroJS.pdf

Review-Url: https://codereview.chromium.org/2235883003
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index 40e1312..ea77e1c 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -749,6 +749,12 @@
 FX_BOOL Document::info(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
+  if (vp.IsSetting()) {
+    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+    sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
+    return FALSE;
+  }
+
   CPDF_Dictionary* pDictionary = m_pDocument->GetPDFDocument()->GetInfo();
   if (!pDictionary)
     return FALSE;
@@ -763,38 +769,36 @@
   CFX_WideString cwModDate = pDictionary->GetUnicodeTextBy("ModDate");
   CFX_WideString cwTrapped = pDictionary->GetUnicodeTextBy("Trapped");
 
-  v8::Isolate* isolate = GetIsolate(cc);
-  if (vp.IsGetting()) {
-    CJS_Context* pContext = (CJS_Context*)cc;
-    CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-    v8::Local<v8::Object> pObj =
-        FXJS_NewFxDynamicObj(pRuntime->GetIsolate(), pRuntime, -1);
-    FXJS_PutObjectString(isolate, pObj, L"Author", cwAuthor);
-    FXJS_PutObjectString(isolate, pObj, L"Title", cwTitle);
-    FXJS_PutObjectString(isolate, pObj, L"Subject", cwSubject);
-    FXJS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords);
-    FXJS_PutObjectString(isolate, pObj, L"Creator", cwCreator);
-    FXJS_PutObjectString(isolate, pObj, L"Producer", cwProducer);
-    FXJS_PutObjectString(isolate, pObj, L"CreationDate", cwCreationDate);
-    FXJS_PutObjectString(isolate, pObj, L"ModDate", cwModDate);
-    FXJS_PutObjectString(isolate, pObj, L"Trapped", cwTrapped);
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Local<v8::Object> pObj =
+      FXJS_NewFxDynamicObj(pRuntime->GetIsolate(), pRuntime, -1);
 
-    // It's to be compatible to non-standard info dictionary.
-    for (const auto& it : *pDictionary) {
-      const CFX_ByteString& bsKey = it.first;
-      CPDF_Object* pValueObj = it.second;
-      CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey.AsStringC());
-      if (pValueObj->IsString() || pValueObj->IsName()) {
-        FXJS_PutObjectString(isolate, pObj, wsKey, pValueObj->GetUnicodeText());
-      } else if (pValueObj->IsNumber()) {
-        FXJS_PutObjectNumber(isolate, pObj, wsKey,
-                             (float)pValueObj->GetNumber());
-      } else if (pValueObj->IsBoolean()) {
-        FXJS_PutObjectBoolean(isolate, pObj, wsKey, !!pValueObj->GetInteger());
-      }
+  v8::Isolate* isolate = GetIsolate(cc);
+  FXJS_PutObjectString(isolate, pObj, L"Author", cwAuthor);
+  FXJS_PutObjectString(isolate, pObj, L"Title", cwTitle);
+  FXJS_PutObjectString(isolate, pObj, L"Subject", cwSubject);
+  FXJS_PutObjectString(isolate, pObj, L"Keywords", cwKeywords);
+  FXJS_PutObjectString(isolate, pObj, L"Creator", cwCreator);
+  FXJS_PutObjectString(isolate, pObj, L"Producer", cwProducer);
+  FXJS_PutObjectString(isolate, pObj, L"CreationDate", cwCreationDate);
+  FXJS_PutObjectString(isolate, pObj, L"ModDate", cwModDate);
+  FXJS_PutObjectString(isolate, pObj, L"Trapped", cwTrapped);
+
+  // It's to be compatible to non-standard info dictionary.
+  for (const auto& it : *pDictionary) {
+    const CFX_ByteString& bsKey = it.first;
+    CPDF_Object* pValueObj = it.second;
+    CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey.AsStringC());
+    if (pValueObj->IsString() || pValueObj->IsName()) {
+      FXJS_PutObjectString(isolate, pObj, wsKey, pValueObj->GetUnicodeText());
+    } else if (pValueObj->IsNumber()) {
+      FXJS_PutObjectNumber(isolate, pObj, wsKey, (float)pValueObj->GetNumber());
+    } else if (pValueObj->IsBoolean()) {
+      FXJS_PutObjectBoolean(isolate, pObj, wsKey, !!pValueObj->GetInteger());
     }
-    vp << pObj;
   }
+  vp << pObj;
   return TRUE;
 }
 
diff --git a/testing/resources/javascript/document_props_expected.txt b/testing/resources/javascript/document_props_expected.txt
index 90914cd..28172ee 100644
--- a/testing/resources/javascript/document_props_expected.txt
+++ b/testing/resources/javascript/document_props_expected.txt
@@ -46,7 +46,7 @@
 Alert: this.external = 3; yields 3
 Alert: ERROR: Document.filesize: Cannot assign to readonly property.
 Alert: ERROR: Document.icons: Cannot assign to readonly property.
-Alert: this.info = 3; yields 3
+Alert: ERROR: Document.info: Cannot assign to readonly property.
 Alert: this.keywords = 3; yields 3
 Alert: this.layout = 3; yields 3
 Alert: this.media = 3; yields 3