fix: prevent pypdfium2 file leak (fixes: #1089)

This commit is contained in:
David Huggins-Daines
2024-02-05 08:52:51 -05:00
parent 07d9997ee5
commit f3d20fcf35
2 changed files with 29 additions and 4 deletions
+5 -4
View File
@@ -53,10 +53,8 @@ def get_page_image(
stream.seek(0)
src = stream
pdfium_page = pypdfium2.PdfDocument(
src,
password=password,
).get_page(page_ix)
pdfium_doc = pypdfium2.PdfDocument(src, password=password)
pdfium_page = pdfium_doc.get_page(page_ix)
img: PIL.Image.Image = pdfium_page.render(
# Modifiable arguments
@@ -67,6 +65,9 @@ def get_page_image(
# Non-modifiable arguments
prefer_bgrx=True,
).to_pil()
# In theory `autoclose` when creating it should make it close...
# automatically. In practice this does not seem to be the case.
pdfium_doc.close()
return img.convert("RGB")
+24
View File
@@ -2,6 +2,11 @@
import logging
import os
import re
try:
import resource
except ModuleNotFoundError:
resource = None
import unittest
import pdfplumber
@@ -275,3 +280,22 @@ class Test(unittest.TestCase):
text = re.sub(r"\s+", " ", page.extract_text(use_text_flow=True))
words = " ".join(w["text"] for w in page.extract_words(use_text_flow=True))
assert text[0:100] == words[0:100]
def test_issue_1089(self):
"""
Page.to_image() leaks file descriptors
This is because PyPdfium2 leaks file descriptors. Explicitly
close the `PdfDocument` to prevent this.
"""
# Skip test on platforms without getrlimit
if resource is None:
return
# Any PDF will do
path = os.path.join(HERE, "pdfs/test-punkt.pdf")
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
with pdfplumber.open(path) as pdf:
for idx in range(soft):
_ = pdf.pages[0].to_image()
# We're still alive
assert True