Skip to content

Commit

Permalink
ENH: Allow setting the decryption password in PdfReader.__init__ (#920)
Browse files Browse the repository at this point in the history
This is a convenience change. You can still call `reader = PdfReader("encrypted.pdf"); reader.decrypt(password)`.

Full credit to pubpub-zz; I just made stylistic changes.

Closes #910 

Co-authored-by: pubpub-zz <[email protected]>
  • Loading branch information
MartinThoma and pubpub-zz authored May 29, 2022
1 parent 7647ab5 commit c59224a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
12 changes: 11 additions & 1 deletion PyPDF2/_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,17 @@ class PdfReader:
:param bool strict: Determines whether user should be warned of all
problems and also causes some correctable problems to be fatal.
Defaults to ``False``.
:param None/str/bytes password: Decrypt PDF file at initialization. If the
password is None, the file will not be decrypted.
Defaults to ``None``
"""

def __init__(self, stream: StrByteType, strict: bool = False) -> None:
def __init__(
self,
stream: StrByteType,
strict: bool = False,
password: Union[None, str, bytes] = None,
) -> None:
self.strict = strict
self.flattened_pages: Optional[List[PageObject]] = None
self.resolved_objects: Dict[Tuple[Any, Any], Optional[PdfObject]] = {}
Expand All @@ -254,6 +262,8 @@ def __init__(self, stream: StrByteType, strict: bool = False) -> None:
self.stream = stream

self._override_encryption = False
if password is not None and self.decrypt(password) == 0:
raise PdfReadError("Wrong password")

@property
def metadata(self) -> Optional[DocumentInformation]:
Expand Down
16 changes: 9 additions & 7 deletions tests/test_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,20 +254,22 @@ def test_issue297():
reader.pages[0]


def test_get_page_of_encrypted_file():
@pytest.mark.parametrize(
("password", "should_fail"), [("test", False), ("qwerty", True)]
)
def test_get_page_of_encrypted_file(password, should_fail):
"""
Check if we can read a page of an encrypted file.
This is a regression test for issue 327:
IndexError for get_page() of decrypted file
"""
path = os.path.join(RESOURCE_ROOT, "encrypted-file.pdf")
reader = PdfReader(path)

# Password is correct:)
reader.decrypt("test")

reader.pages[0]
if should_fail:
with pytest.raises(PdfReadError):
PdfReader(path, password=password)
else:
PdfReader(path, password=password).pages[0]


@pytest.mark.parametrize(
Expand Down

0 comments on commit c59224a

Please sign in to comment.