From d2e27d660a96080882e43825fb4b5d03e8a4d05a Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 15 Oct 2018 21:57:32 +0000 Subject: Clone dict before iteration in CJS_Document::get_info Bug: 895152 Change-Id: I678350841892f88a5d580b58a33a639a1b6ec305 Reviewed-on: https://pdfium-review.googlesource.com/c/44050 Reviewed-by: Lei Zhang Commit-Queue: Tom Sepez --- fxjs/cjs_document.cpp | 5 +- testing/resources/javascript/bug_895152.in | 74 ++++++++++++++++++++++ .../resources/javascript/bug_895152_expected.txt | 1 + 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 testing/resources/javascript/bug_895152.in create mode 100644 testing/resources/javascript/bug_895152_expected.txt diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp index f682ffd636..adf36be403 100644 --- a/fxjs/cjs_document.cpp +++ b/fxjs/cjs_document.cpp @@ -740,8 +740,9 @@ CJS_Result CJS_Document::get_info(CJS_Runtime* pRuntime) { pRuntime->PutObjectProperty(pObj, L"Trapped", pRuntime->NewString(cwTrapped.AsStringView())); - // It's to be compatible to non-standard info dictionary. - for (const auto& it : *pDictionary) { + // PutObjectProperty() calls below may re-enter JS and change info dict. + auto pCopy = pDictionary->Clone(); + for (const auto& it : *ToDictionary(pCopy.get())) { const ByteString& bsKey = it.first; CPDF_Object* pValueObj = it.second.get(); WideString wsKey = WideString::FromUTF8(bsKey.AsStringView()); diff --git a/testing/resources/javascript/bug_895152.in b/testing/resources/javascript/bug_895152.in new file mode 100644 index 0000000000..3640274958 --- /dev/null +++ b/testing/resources/javascript/bug_895152.in @@ -0,0 +1,74 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R + /AcroForm 4 0 R + /OpenAction 7 0 R +>> +endobj +{{object 2 0}} << + /Type /Pages + /Count 1 + /Kids [3 0 R ] +>> +endobj +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /MediaBox [0 0 600 700] + /Resources <<>> + /Annots [5 0 R] +>> +endobj +{{object 4 0}} << + /Fields [5 0 R] +>> +endobj +{{object 5 0}} << + /V /TestV + /FT /Tx + /Type /Annot + /Subtype /Widget + /T (txt1) + /F 4 + /AP <> + /Rect [200 200 400 400] +>> +endobj +{{object 6 0}} << + /Type /XObject + /Subtype /Form + /FormType 1 +>> +endobj +{{object 7 0}} << + /Type /Action + /S /JavaScript + /JS 8 0 R +>> +endobj +{{object 8 0}} <<>> +stream +function run() { + var doc = this; + Object.prototype.__defineSetter__('V', function() { + doc.resetForm(); + }); + var other_info = this.info; +} +try { + run(); + app.alert('*** PASS ***'); +} catch (e) { + app.alert('Caught: ' + e); +} +endstream +endobj +{{xref}} +trailer << + /Root 1 0 R + /Info 5 0 R +>> +{{startxref}} +%%EOF + diff --git a/testing/resources/javascript/bug_895152_expected.txt b/testing/resources/javascript/bug_895152_expected.txt new file mode 100644 index 0000000000..a7c97beb25 --- /dev/null +++ b/testing/resources/javascript/bug_895152_expected.txt @@ -0,0 +1 @@ +Alert: *** PASS *** -- cgit v1.2.3