summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-08-05 17:12:27 -0700
committerCommit bot <commit-bot@chromium.org>2016-08-05 17:12:27 -0700
commit8ca63de14d522d3d259d74fa43b28b05b02728e8 (patch)
treedd86d4b10e658cef8bf5fea5d99baa1d15bda7ca /testing
parent135b99861d0d898850754a845f607ec48f0bcccc (diff)
downloadpdfium-8ca63de14d522d3d259d74fa43b28b05b02728e8.tar.xz
Remove another potential stale CJS_Timer usage
Fix memory ownership model for PDFium timers. The |app| class owns the CJS_Timer as part of its vector<unique_ptr> to them. The CJS_Timer "owns" its slot in the global ID to timer map, and removes itself when it is destroyed. Nothing else deletes from the global map. Deleting from the global map is accompanied by a callback to the embedder to clear its resources. Next, the proper way to remove a CJS_Timer is by going through the app, and having the app erase its unique ptr, which then deletes the CJS_Timer, which in turn cleans up the global map. Provide a CJS_Timer::Cancel static method to do this conveniently. There is a alternate path to the CJS_timer via JS and its CJS_TimerObj. CJS_TimerObj owns a TimerObj that currently points to the CJS_Timer. If the timer fires, and cleans itself up, this can go stale. Make the TimerObj maintain a weak reference via global timer ID rather than a direct pointer to the CJS_Timer, so that if the timer fires and is destroyed, future attempts to cancel find nothing. There is another path, where if the JS timer object is GC'd, then we just clean up its CJS_TimerObj without touching the actual CJS_Timers. We could make this match the spec by calling into the new cancel routine as described above, but it seems weird to have a timer depend on whether a gc happened or not. A subsequent CL will rename these objects to more closely match the conventions used by the other JS wrappers. BUG=634716 Review-Url: https://codereview.chromium.org/2221513002
Diffstat (limited to 'testing')
-rw-r--r--testing/resources/bug_634716.in126
-rw-r--r--testing/resources/bug_634716.pdf180
2 files changed, 306 insertions, 0 deletions
diff --git a/testing/resources/bug_634716.in b/testing/resources/bug_634716.in
new file mode 100644
index 0000000000..a485daed97
--- /dev/null
+++ b/testing/resources/bug_634716.in
@@ -0,0 +1,126 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm 6 0 R
+ /Names <</JavaScript 13 0 R>>
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 1
+ /Kids [4 0 R]
+>>
+endobj
+{{object 4 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /CropBox [0 0 612 792]
+ /Resources <<>>
+>>
+endobj
+{{object 6 0}} <<
+ /DR <<
+ /Font <</Helv 7 0 R>>
+ >>
+ /DA (/Helv 0 Tf 0 g)
+ /Fields [5 0 R]
+>>
+endobj
+{{object 7 0}} <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+>>
+endobj
+{{object 8 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Matrix [1 0 0 1 0 0]
+ /BBox [0 0 75.907 28.472]
+ /Resources <<
+ /Font <</FXF0 7 0 R>>
+ >>
+>>
+stream
+q
+Q
+
+
+endstream
+endobj
+{{object 11 0}} <<
+ /Type /Action
+ /S /JavaScript
+ /JS 50 0 R
+>>
+endobj
+{{object 13 0}} <<
+ /Names [(startDelay) 11 0 R]
+>>
+endobj
+{{object 50 0}} <<
+>>
+stream
+var timeOut = 0;
+var array = new Array(1024*4);
+var doc = this;
+
+function myFunction() {
+ try {
+ // Free the Timer Objects
+ app.clearTimeOut(timeOut);
+ for (var i=0; i<array.length; i++) {
+ for (var j=0; j<array[i].length; j++) {
+ app.clearTimeOut(array[i][j]);
+ }
+ }
+
+ // Trigger the Garbage Collection
+ array.length = 0;
+ array.push(new ArrayBuffer(1024*1024));
+ array.length=0;
+ array.length=1024*4;
+ var str = 'AA';
+ for (var i = 0; i < array.length ; i++) {
+ for (var j = 0; j < 10; j++ ) {
+ doc.addIcon(str + "-" + str + str + str + str + str, doc.icons);
+ }
+ }
+ } catch(err) {
+ app.alert(err);
+ }
+}
+
+function main() {
+ try {
+ for (var i = 0; i < array.length ; i++) {
+ if (i == array.length / 2) {
+ timeOut = app.setTimeOut("myFunction()", 1000);
+ }
+ array[i] = new Array(4);
+ for (var j = 0; j < array[i].length ; j++ ) {
+ array[i][j] = app.setTimeOut("aaaaaaaaaa()", 100000);
+ }
+ }
+ } catch(err) {
+ app.alert(err);
+ }
+}
+
+// Execute the JS.
+app.setTimeOut("main()", 1000);
+
+// Be sure all of this code ran to completion.
+app.alert("done");
+endstream
+endobj
+{{xref}}
+trailer <<
+ /Root 1 0 R
+>>
+{{startxref}}
+%%EOF
diff --git a/testing/resources/bug_634716.pdf b/testing/resources/bug_634716.pdf
new file mode 100644
index 0000000000..6330b9a4e5
--- /dev/null
+++ b/testing/resources/bug_634716.pdf
@@ -0,0 +1,180 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm 6 0 R
+ /Names <</JavaScript 13 0 R>>
+>>
+endobj
+2 0 obj <<
+ /Type /Pages
+ /Count 1
+ /Kids [4 0 R]
+>>
+endobj
+4 0 obj <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 612 792]
+ /CropBox [0 0 612 792]
+ /Resources <<>>
+>>
+endobj
+6 0 obj <<
+ /DR <<
+ /Font <</Helv 7 0 R>>
+ >>
+ /DA (/Helv 0 Tf 0 g)
+ /Fields [5 0 R]
+>>
+endobj
+7 0 obj <<
+ /Type /Font
+ /Subtype /Type1
+ /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+>>
+endobj
+8 0 obj <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /Matrix [1 0 0 1 0 0]
+ /BBox [0 0 75.907 28.472]
+ /Resources <<
+ /Font <</FXF0 7 0 R>>
+ >>
+>>
+stream
+q
+Q
+
+
+endstream
+endobj
+11 0 obj <<
+ /Type /Action
+ /S /JavaScript
+ /JS 50 0 R
+>>
+endobj
+13 0 obj <<
+ /Names [(startDelay) 11 0 R]
+>>
+endobj
+50 0 obj <<
+>>
+stream
+var timeOut = 0;
+var array = new Array(1024*4);
+var doc = this;
+
+function myFunction() {
+ try {
+ // Free the Timer Objects
+ app.clearTimeOut(timeOut);
+ for (var i=0; i<array.length; i++) {
+ for (var j=0; j<array[i].length; j++) {
+ app.clearTimeOut(array[i][j]);
+ }
+ }
+
+ // Trigger the Garbage Collection
+ array.length = 0;
+ array.push(new ArrayBuffer(1024*1024));
+ array.length=0;
+ array.length=1024*4;
+ var str = 'AA';
+ for (var i = 0; i < array.length ; i++) {
+ for (var j = 0; j < 10; j++ ) {
+ doc.addIcon(str + "-" + str + str + str + str + str, doc.icons);
+ }
+ }
+ } catch(err) {
+ app.alert(err);
+ }
+}
+
+function main() {
+ try {
+ for (var i = 0; i < array.length ; i++) {
+ if (i == array.length / 2) {
+ timeOut = app.setTimeOut("myFunction()", 1000);
+ }
+ array[i] = new Array(4);
+ for (var j = 0; j < array[i].length ; j++ ) {
+ array[i][j] = app.setTimeOut("aaaaaaaaaa()", 100000);
+ }
+ }
+ } catch(err) {
+ app.alert(err);
+ }
+}
+
+// Execute the JS.
+app.setTimeOut("main()", 1000);
+
+// Be sure all of this code ran to completion.
+app.alert("done");
+endstream
+endobj
+xref
+0 51
+0000000000 65535 f
+0000000015 00000 n
+0000000118 00000 n
+0000000000 65535 f
+0000000181 00000 n
+0000000000 65535 f
+0000000302 00000 n
+0000000404 00000 n
+0000000509 00000 n
+0000000000 65535 f
+0000000000 65535 f
+0000000701 00000 n
+0000000000 65535 f
+0000000769 00000 n
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000000 65535 f
+0000000822 00000 n
+trailer <<
+ /Root 1 0 R
+>>
+startxref
+2036
+%%EOF