A pure-python PDF library capable of splitting, merging, cropping, and transforming the pages of PDF files
This report presents the forensic synthetic code analysis of py-pdf/pypdf, a Python project with 10,115 GitHub stars. SynthScan v2.0 examined 77,724 lines of code across 181 source files, recording 1059 pattern matches distributed across 20 syntactic categories. The overall adjusted score of 14.5 places this repository in the Low AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 1059 distinct pattern matches across 20 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | make_release.py | 305 | def get_git_commits_since_tag(git_tag: str) -> list[Change]: | CODE |
| LOW | tests/test_forms.py | 12 | def test_form_button__v_value_should_be_name_object(): | CODE |
| LOW | tests/test_workflows.py | 116 | def test_pdfreader_jpeg_image(): | CODE |
| LOW⚡ | tests/test_workflows.py | 154 | def test_text_extraction_encrypted(): | CODE |
| LOW | tests/test_workflows.py | 267 | def test_transform_compress_identical_objects(): | CODE |
| LOW | tests/test_workflows.py | 572 | def test_get_fields_no_warning(tmp_path, url, name): | CODE |
| LOW | tests/test_workflows.py | 583 | def test_scale_rectangle_indirect_object(): | CODE |
| LOW | tests/test_workflows.py | 694 | def test_image_extraction_strict(): | CODE |
| LOW | tests/test_workflows.py | 887 | def test_tounicode_is_identity(): | CODE |
| LOW | tests/test_workflows.py | 951 | def test_fields_returning_stream(): | CODE |
| LOW | tests/test_workflows.py | 1070 | def test_cr_with_cm_operation(): | CODE |
| LOW | tests/test_workflows.py | 1087 | def remove_trailing_whitespace(text: str) -> str: | CODE |
| LOW | tests/test_workflows.py | 1106 | def test_text_extraction_layout_mode(pdf_path, expected_path): | CODE |
| LOW | tests/test_workflows.py | 1115 | def test_layout_mode_space_vertically(): | CODE |
| LOW | tests/test_workflows.py | 1130 | def test_layout_mode_rotations(rotation, strip_rotated): | CODE |
| LOW | tests/test_workflows.py | 1148 | def test_text_extraction_invalid_mode(): | CODE |
| LOW | tests/test_workflows.py | 1156 | def test_get_page_showing_field(): | CODE |
| LOW⚡ | tests/test_reader.py | 1469 | def test_outline_with_missing_named_destination(): | CODE |
| LOW⚡ | tests/test_reader.py | 1478 | def test_outline_with_empty_action(): | CODE |
| LOW⚡ | tests/test_reader.py | 1487 | def test_outline_with_invalid_destinations(): | CODE |
| LOW⚡ | tests/test_reader.py | 1495 | def test_pdfreader_multiple_definitions(caplog): | CODE |
| LOW⚡ | tests/test_reader.py | 1506 | def test_wrong_password_error(): | CODE |
| LOW⚡ | tests/test_reader.py | 1515 | def test_get_page_number_by_indirect(): | CODE |
| LOW⚡ | tests/test_reader.py | 1521 | def test_corrupted_xref_table(): | CODE |
| LOW | tests/test_reader.py | 377 | def test_startxref_corrupt_trailing_pointer(caplog): | CODE |
| LOW | tests/test_reader.py | 431 | def test_find_previous_startxref_pos_recovery_variants(): | CODE |
| LOW | tests/test_reader.py | 468 | def test_get_page_of_encrypted_file(pdffile, password, should_fail): | CODE |
| LOW | tests/test_reader.py | 536 | def test_reading_choice_field_without_opt_key(): | CODE |
| LOW | tests/test_reader.py | 594 | def test_read_malformed_header(caplog): | CODE |
| LOW | tests/test_reader.py | 651 | def test_circular_xref_prev_reference(caplog): | CODE |
| LOW | tests/test_reader.py | 985 | def test_user_access_permissions(): | CODE |
| LOW | tests/test_reader.py | 1050 | def test_convert_to_int_error(): | CODE |
| LOW | tests/test_reader.py | 1076 | def test_extract_text_hello_world(): | CODE |
| LOW | tests/test_reader.py | 1101 | def test_read_not_binary_mode(caplog): | CODE |
| LOW | tests/test_reader.py | 1123 | def test_form_topname_with_and_without_acroform(caplog): | CODE |
| LOW | tests/test_reader.py | 1211 | def test_get_full_qualified_fields(): | CODE |
| LOW | tests/test_reader.py | 1232 | def test_get_fields_read_else_block(): | CODE |
| LOW | tests/test_reader.py | 1265 | def test_get_fields_read_write_report(txt_file_path): | CODE |
| LOW | tests/test_reader.py | 1433 | def test_outline_missing_title(caplog): | CODE |
| LOW | tests/test_reader.py | 1740 | def test_xyz_with_missing_param(): | CODE |
| LOW | tests/test_reader.py | 1808 | def test_context_manager_with_stream(): | CODE |
| LOW | tests/test_reader.py | 1905 | def test_space_in_names_to_continue_processing(caplog): | CODE |
| LOW | tests/test_reader.py | 1951 | def test_unbalanced_brackets_in_dictionary_object(caplog): | CODE |
| LOW | tests/test_reader.py | 2062 | def test_infinite_loop_for_length_value(): | CODE |
| LOW | tests/test_reader.py | 2075 | def test_trailer_cannot_be_read(): | CODE |
| LOW | tests/test_reader.py | 2099 | def test_read_standard_xref_table__two_whitespace_characters_between_offset_and_generation(): | CODE |
| LOW | tests/test_reader.py | 2109 | def test_read_standard_xref_table__entry_invalid_but_object_found(caplog): | CODE |
| LOW | tests/test_reader.py | 2136 | def test_root_object_recovery_limit(caplog): | CODE |
| LOW | tests/test_reader.py | 2179 | def test_rebuild_xref_table__speed(): | CODE |
| LOW | tests/test_reader.py | 2222 | def test_cache_indirect_object_strict_overwrite_error(): | CODE |
| LOW | tests/test_reader.py | 2230 | def test_objstm_batch_parse_caches_all_objects(): | CODE |
| LOW | tests/test_reader.py | 2244 | def test_objstm_cache_hit_returns_target(): | CODE |
| LOW | tests/test_reader.py | 2259 | def test_objstm_skips_cache_for_overridden_objects(): | CODE |
| LOW | tests/test_reader.py | 2278 | def test_objstm_does_not_cache_stale_objects_from_non_authoritative_stream(): | CODE |
| LOW | tests/test_reader.py | 2367 | def test_xref_table_with_comments_before_trailer(): | CODE |
| LOW | tests/test_reader.py | 2457 | def test_get_object_from_stream__size_limit(caplog): | CODE |
| LOW | tests/test_reader.py | 2507 | def test_named_destinations_cache(): | CODE |
| LOW | tests/test_reader.py | 2518 | def test_read_standard_xref_table__malformed__speed(): | CODE |
| LOW⚡ | tests/test_reader.py | 856 | def test_read_encrypted_without_decryption(): | STRING |
| LOW⚡ | tests/test_reader.py | 864 | def test_get_destination_page_number(): | STRING |
| 571 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pypdf/__init__.py | 11 | CODE | |
| LOW | pypdf/__init__.py | 12 | CODE | |
| LOW | pypdf/__init__.py | 13 | CODE | |
| LOW | pypdf/__init__.py | 13 | CODE | |
| LOW | pypdf/__init__.py | 14 | CODE | |
| LOW | pypdf/__init__.py | 15 | CODE | |
| LOW | pypdf/__init__.py | 17 | CODE | |
| LOW | pypdf/__init__.py | 17 | CODE | |
| LOW | pypdf/__init__.py | 18 | CODE | |
| LOW | pypdf/__init__.py | 19 | CODE | |
| LOW | pypdf/__init__.py | 19 | CODE | |
| LOW | pypdf/__init__.py | 20 | CODE | |
| LOW | pypdf/_font.py | 1 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 28 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 28 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 31 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 44 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/_crypt_providers/__init__.py | 56 | CODE | |
| LOW | pypdf/annotations/__init__.py | 14 | CODE | |
| LOW | pypdf/annotations/__init__.py | 14 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 15 | CODE | |
| LOW | pypdf/annotations/__init__.py | 26 | CODE | |
| LOW | pypdf/annotations/__init__.py | 26 | CODE | |
| LOW | pypdf/_text_extraction/_layout_mode/__init__.py | 2 | CODE | |
| LOW | pypdf/_text_extraction/_layout_mode/__init__.py | 3 | CODE | |
| LOW | pypdf/_text_extraction/_layout_mode/__init__.py | 3 | CODE | |
| LOW | pypdf/_text_extraction/_layout_mode/__init__.py | 3 | CODE | |
| LOW | pypdf/_text_extraction/_layout_mode/__init__.py | 3 | CODE | |
| 45 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | resources/afm_to_dataclass.py | 23 | CODE | |
| LOW | resources/afm_to_dataclass.py | 50 | CODE | |
| LOW | tests/test_workflows.py | 668 | CODE | |
| LOW | tests/test_reader.py | 171 | CODE | |
| LOW | tests/test_reader.py | 188 | CODE | |
| LOW | tests/test_font.py | 105 | CODE | |
| LOW | tests/utils.py | 111 | CODE | |
| LOW | pypdf/_page_labels.py | 188 | CODE | |
| LOW | pypdf/_encryption.py | 73 | CODE | |
| LOW | pypdf/_encryption.py | 96 | CODE | |
| LOW | pypdf/_encryption.py | 1045 | CODE | |
| LOW | pypdf/_writer.py | 754 | CODE | |
| LOW | pypdf/_writer.py | 942 | CODE | |
| LOW | pypdf/_writer.py | 1440 | CODE | |
| LOW | pypdf/_writer.py | 1828 | CODE | |
| LOW | pypdf/_writer.py | 1981 | CODE | |
| LOW | pypdf/_writer.py | 2107 | CODE | |
| LOW | pypdf/_writer.py | 2214 | CODE | |
| LOW | pypdf/_writer.py | 2553 | CODE | |
| LOW | pypdf/_writer.py | 2684 | CODE | |
| LOW | pypdf/_writer.py | 2840 | CODE | |
| LOW | pypdf/_writer.py | 3001 | CODE | |
| LOW | pypdf/_writer.py | 3198 | CODE | |
| LOW | pypdf/_reader.py | 456 | CODE | |
| LOW | pypdf/_reader.py | 675 | CODE | |
| LOW | pypdf/_reader.py | 892 | CODE | |
| LOW | pypdf/_reader.py | 1026 | CODE | |
| LOW | pypdf/_reader.py | 1158 | CODE | |
| LOW | pypdf/_reader.py | 1349 | CODE | |
| LOW | pypdf/_reader.py | 1409 | CODE | |
| LOW | pypdf/xmp.py | 271 | CODE | |
| LOW | pypdf/xmp.py | 355 | CODE | |
| LOW | pypdf/xmp.py | 629 | CODE | |
| LOW | pypdf/_page.py | 814 | CODE | |
| LOW | pypdf/_page.py | 960 | CODE | |
| LOW | pypdf/_page.py | 1042 | CODE | |
| LOW | pypdf/_page.py | 1634 | CODE | |
| LOW | pypdf/_page.py | 1791 | CODE | |
| LOW | pypdf/_page.py | 2060 | CODE | |
| LOW | pypdf/_doc_common.py | 449 | CODE | |
| LOW | pypdf/_doc_common.py | 612 | CODE | |
| LOW | pypdf/_doc_common.py | 675 | CODE | |
| LOW | pypdf/_doc_common.py | 750 | CODE | |
| LOW | pypdf/_doc_common.py | 995 | CODE | |
| LOW | pypdf/_doc_common.py | 1162 | CODE | |
| LOW | pypdf/_doc_common.py | 1379 | CODE | |
| LOW | pypdf/_doc_common.py | 1437 | CODE | |
| LOW | pypdf/_font.py | 313 | CODE | |
| LOW | pypdf/_font.py | 459 | CODE | |
| LOW | pypdf/_font.py | 556 | CODE | |
| LOW | pypdf/_cmap.py | 63 | CODE | |
| LOW | pypdf/_cmap.py | 198 | CODE | |
| LOW | pypdf/_cmap.py | 239 | CODE | |
| LOW | pypdf/_cmap.py | 336 | CODE | |
| LOW | pypdf/filters.py | 100 | CODE | |
| LOW | pypdf/filters.py | 803 | CODE | |
| LOW | pypdf/filters.py | 173 | CODE | |
| LOW | pypdf/filters.py | 259 | CODE | |
| LOW | pypdf/filters.py | 411 | CODE | |
| LOW | pypdf/filters.py | 637 | CODE | |
| 27 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | make_release.py | 337 | Parse the first line of a git commit message. Args: line: The first line of a git commit message. | STRING |
| HIGH | docs/dev/documentation.md | 48 | Example function with PEP 484 type annotations. Args: param1: The first parameter. param2: The sec | STRING |
| HIGH | pypdf/_encryption.py | 788 | Apply the SASLprep profile (RFC 4013) of stringprep (RFC 3454). This normalizes Unicode passwords for PDF 2.0 | STRING |
| HIGH | pypdf/_writer.py | 685 | Append a blank page to this PDF file and return it. If no page size is specified, use the size of the | STRING |
| HIGH | pypdf/_writer.py | 713 | Insert a blank page to this PDF file and return it. If no page size is specified for a dimension, use | STRING |
| HIGH | pypdf/_page.py | 578 | Return a new blank page. If ``width`` or ``height`` is ``None``, try to get the page size from | STRING |
| HIGH | pypdf/filters.py | 178 | Decode data which is flate-encoded. Args: data: Flate-encoded data. decode_parms: | STRING |
| HIGH | pypdf/filters.py | 350 | Decode an ASCII-Hex encoded data stream. Args: data: a str sequence of hexadecimal-encoded v | STRING |
| HIGH | pypdf/filters.py | 416 | Decode a run length encoded data stream. Args: data: a bytes sequence of length/data | STRING |
| HIGH | pypdf/filters.py | 804 | Decode the stream data based on the specified filters. This function decodes the stream data using the filters | STRING |
| HIGH | …f/_text_extraction/_layout_mode/_text_state_manager.py | 79 | Create a TextStateParams instance to display a text string. Type[bytes] values will be decoded implicit | STRING |
| HIGH | pypdf/generic/_image_xobject.py | 447 | Users need to have the pillow package installed. It's unclear if pypdf will keep this function here, hence it' | STRING |
| HIGH | pypdf/generic/_data_structures.py | 1107 | Try to decode the stream object as an image Args: pillow_parameters: parameters provided t | STRING |
| HIGH | pypdf/generic/_utils.py | 134 | Create a ByteStringObject or a TextStringObject from a string to represent the string. Args: string: T | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | resources/afm_to_dataclass.py | 39 | "# This file is based upon the 14 core AFM files provided by Adobe/Macromedia at\n# " + | CODE |
| MEDIUM | tests/test_generic.py | 990 | # Create a weak reference to the underlying object to test later | COMMENT |
| MEDIUM | tests/test_generic.py | 1018 | # Create a weak reference to the underlying object to test later | COMMENT |
| MEDIUM | tests/generic/test_data_structures.py | 100 | # Create a single child A as the /First (and /Last) | COMMENT |
| MEDIUM | .github/workflows/release.yaml | 30 | contents: write # Create the actual release. | CODE |
| MEDIUM | pypdf/_writer.py | 883 | # Create a new StreamObject for the new_content_data | COMMENT |
| MEDIUM | pypdf/_writer.py | 896 | # Create a new StreamObject in a new /Contents entry. | COMMENT |
| MEDIUM | pypdf/_writer.py | 2726 | # Create a new PdfReader instance using the stream | COMMENT |
| MEDIUM | pypdf/_font.py | 661 | # Create the descendant font object | COMMENT |
| MEDIUM | pypdf/_font.py | 677 | # Create the Type 0 font object | COMMENT |
| MEDIUM | pypdf/filters.py | 622 | # Create an alias for the old class name | COMMENT |
| MEDIUM | pypdf/_utils.py | 516 | # The following class has been copied from Django: | COMMENT |
| MEDIUM | pypdf/generic/_files.py | 73 | # Create the file entry (the actual embedded file stream) | COMMENT |
| MEDIUM | pypdf/generic/_files.py | 82 | # Create the filespec dictionary | COMMENT |
| MEDIUM | pypdf/generic/_appearance_stream.py | 574 | # Create a default appearance if none was found in the annotation | COMMENT |
| MEDIUM | pypdf/generic/_appearance_stream.py | 649 | # Create the TextStreamAppearance instance | COMMENT |
| MEDIUM | pypdf/generic/_link.py | 28 | # This module contains code used by _writer.py to track links in pages | COMMENT |
| MEDIUM⚡ | pypdf/_codecs/core_font_metrics.py | 1 | # This file is based upon the 14 core AFM files provided by Adobe/Macromedia at | COMMENT |
| MEDIUM | pypdf/_codecs/_codecs.py | 180 | # The following method has been converted to Python from PDFsharp: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | make_release.py | 104 | except Exception: | CODE |
| LOW | tests/test_reader.py | 601 | except Exception: | CODE |
| LOW | tests/test_page.py | 67 | except Exception: | CODE |
| LOW | docs/user/suppress-warnings.md | 45 | except Exception as exc: | CODE |
| LOW | docs/user/extract-images.md | 64 | except Exception as exception: | CODE |
| LOW | .github/scripts/check_urls.py | 52 | except Exception as exception: | CODE |
| LOW | .github/scripts/check_gh_pages_updates.py | 66 | except Exception as e: | CODE |
| LOW | .github/scripts/check_gh_pages_updates.py | 82 | except Exception as e: | CODE |
| LOW | pypdf/_encryption.py | 1068 | except Exception: | CODE |
| MEDIUM | pypdf/_writer.py | 2348 | def _get_page_layout(self) -> Optional[LayoutType]: | CODE |
| LOW | pypdf/_writer.py | 522 | except Exception: | CODE |
| LOW | pypdf/_writer.py | 590 | except Exception as exc: # pragma: no cover | CODE |
| LOW | pypdf/_writer.py | 2998 | except Exception: | CODE |
| LOW | pypdf/_writer.py | 3216 | except Exception: | CODE |
| LOW | pypdf/_writer.py | 3221 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 245 | except Exception: # to be sure to capture all errors | CODE |
| LOW | pypdf/_reader.py | 488 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 956 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 1000 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 1004 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 1056 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 1061 | except Exception as e: | CODE |
| LOW | pypdf/_reader.py | 1106 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 1154 | except Exception: | CODE |
| LOW | pypdf/_reader.py | 1398 | except Exception: # could be multiple causes | CODE |
| LOW | pypdf/_page.py | 1773 | except Exception: | CODE |
| LOW | pypdf/_page.py | 1784 | except Exception: | CODE |
| LOW | pypdf/_page.py | 1945 | except Exception as exception: | CODE |
| LOW | pypdf/_page.py | 2417 | except Exception: # pragma: no cover | CODE |
| LOW | pypdf/_doc_common.py | 775 | except Exception as exc: | CODE |
| LOW | pypdf/_doc_common.py | 835 | except Exception as exc: | CODE |
| LOW | pypdf/_cmap.py | 90 | except Exception: | CODE |
| LOW | pypdf/_cmap.py | 96 | except Exception: | CODE |
| LOW | pypdf/_cmap.py | 114 | except Exception: | CODE |
| LOW | pypdf/_text_extraction/__init__.py | 148 | except Exception: | CODE |
| LOW | pypdf/_text_extraction/__init__.py | 180 | except Exception: | CODE |
| LOW | pypdf/_text_extraction/_text_extractor.py | 250 | except Exception: | CODE |
| LOW | pypdf/_text_extraction/_text_extractor.py | 261 | except Exception: | CODE |
| LOW | pypdf/_text_extraction/_text_extractor.py | 305 | except Exception: | CODE |
| LOW | pypdf/generic/_base.py | 162 | except Exception: | CODE |
| LOW | pypdf/generic/_base.py | 496 | except Exception as e: | CODE |
| LOW | pypdf/generic/_base.py | 921 | except Exception: | CODE |
| LOW | pypdf/generic/_image_xobject.py | 620 | except Exception as exception: | CODE |
| LOW⚡ | pypdf/generic/_data_structures.py | 1762 | except Exception: | CODE |
| LOW⚡ | pypdf/generic/_data_structures.py | 1767 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 127 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 300 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 405 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 625 | except Exception as exc: | CODE |
| LOW | pypdf/generic/_data_structures.py | 836 | except Exception: # it means we are inserting in first position | CODE |
| LOW | pypdf/generic/_data_structures.py | 982 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 1018 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 1284 | except Exception: | CODE |
| LOW | pypdf/generic/_data_structures.py | 1318 | except Exception: | CODE |
| LOW | pypdf/generic/_utils.py | 156 | except Exception: | CODE |
| LOW | pypdf/_codecs/__init__.py | 13 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | resources/multicolumn-lorem-ipsum.txt | 1 | Two-Column Document with Lorem Ipsum | CODE |
| LOW⚡ | resources/multicolumn-lorem-ipsum.txt | 9 | with Lorem Ipsum text. nas lacinia. Nam ipsum ligula, eleifend at, accumsan | CODE |
| LOW⚡ | resources/multicolumn-lorem-ipsum.txt | 10 | Lorem ipsum dolor sit amet, consectetuer adip- nec, suscipit a, ipsum. Morbi blandit ligula feugiat | CODE |
| LOW⚡ | resources/multicolumn-lorem-ipsum.txt | 10 | Lorem ipsum dolor sit amet, consectetuer adip- nec, suscipit a, ipsum. Morbi blandit ligula feugiat | CODE |
| LOW⚡ | resources/multicolumn-lorem-ipsum.txt | 20 | placerat. Integer sapien est, iaculis in, pretium quis, ipsum dolor sit amet, consectetuer adipiscing elit. In | CODE |
| LOW⚡ | tests/test_workflows.py | 163 | .startswith("Lorem ipsum dolor sit amet") | CODE |
| LOW⚡ | tests/test_workflows.py | 163 | .startswith("Lorem ipsum dolor sit amet") | CODE |
| LOW⚡ | tests/test_cmap.py | 296 | assert "Lorem ipsum dolor sit amet" in reader.pages[0].extract_text() | CODE |
| LOW⚡ | tests/test_cmap.py | 296 | assert "Lorem ipsum dolor sit amet" in reader.pages[0].extract_text() | CODE |
| LOW | tests/test_cmap.py | 322 | assert page.extract_text() == "Lorem ipsum" | CODE |
| LOW⚡ | tests/test_writer.py | 459 | assert "Lorem ipsum dolor sit amet" in extracted_text | CODE |
| LOW⚡ | tests/test_writer.py | 459 | assert "Lorem ipsum dolor sit amet" in extracted_text | CODE |
| LOW | tests/test_xmp.py | 29 | assert xmp.dc_creator == ["John Doe"] | CODE |
| LOW | tests/test_xmp.py | 47 | assert xmp.dc_creator == ["John Doe"] | CODE |
| LOW⚡ | tests/generic/test_data_structures.py | 170 | assert ContentStream(stream=array2, pdf=None).get_data() == b"Lorem ipsum!\nShared stream 0\nShared stream 2\n" | CODE |
| LOW⚡ | tests/generic/test_data_structures.py | 177 | b"Lorem ipsum!\nShared stream 0\nShared stream 1\nShared stream 2\n" | CODE |
| LOW | tests/generic/test_data_structures.py | 143 | stream2.set_data(b"Lorem ipsum!") | CODE |
| LOW⚡ | tests/generic/test_files.py | 114 | assert attachment.content.startswith(b"Hello World!\n\nLorem ipsum dolor sit amet, ") | CODE |
| LOW⚡ | tests/generic/test_files.py | 114 | assert attachment.content.startswith(b"Hello World!\n\nLorem ipsum dolor sit amet, ") | CODE |
| LOW⚡ | tests/generic/test_files.py | 115 | assert attachment.content.endswith(b"\ntakimata sanctus est Lorem ipsum dolor sit amet.\n") | CODE |
| LOW⚡ | tests/generic/test_files.py | 115 | assert attachment.content.endswith(b"\ntakimata sanctus est Lorem ipsum dolor sit amet.\n") | CODE |
| LOW⚡ | tests/generic/test_files.py | 294 | embedded_file.content = "Lorem ipsum dolor sit amet" | CODE |
| LOW⚡ | tests/generic/test_files.py | 294 | embedded_file.content = "Lorem ipsum dolor sit amet" | CODE |
| LOW⚡ | tests/generic/test_files.py | 295 | assert embedded_file.content == b"Lorem ipsum dolor sit amet" | CODE |
| LOW⚡ | tests/generic/test_files.py | 295 | assert embedded_file.content == b"Lorem ipsum dolor sit amet" | CODE |
| LOW⚡ | tests/generic/test_files.py | 478 | b"Hello World!\n\nLorem ipsum dolor sit amet, consetetur sad" | CODE |
| LOW⚡ | tests/generic/test_files.py | 478 | b"Hello World!\n\nLorem ipsum dolor sit amet, consetetur sad" | CODE |
| LOW⚡ | tests/generic/test_files.py | 483 | b"t Lorem\nipsum dolor sit amet. Lorem ipsum dolor sit amet" | CODE |
| LOW⚡ | tests/generic/test_files.py | 483 | b"t Lorem\nipsum dolor sit amet. Lorem ipsum dolor sit amet" | CODE |
| LOW⚡ | tests/generic/test_files.py | 488 | b"imata sanctus est Lorem ipsum dolor sit amet.\n" | CODE |
| LOW⚡ | tests/generic/test_files.py | 488 | b"imata sanctus est Lorem ipsum dolor sit amet.\n" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_encryption.py | 41 | # qpdf --encrypt "asdfzxcv" "" 128 -- unencrypted.pdf r3-user-password.pdf | COMMENT |
| LOW | requirements/dev.txt | 1 | # | COMMENT |
| LOW | requirements/dev.txt | 41 | packaging==24.1 | COMMENT |
| LOW | requirements/dev.txt | 61 | # via pytest-cov | COMMENT |
| LOW | requirements/dev.txt | 81 | # via pre-commit | COMMENT |
| LOW | requirements/ci.txt | 1 | # | COMMENT |
| LOW | requirements/ci.txt | 21 | fonttools==4.60.2 | COMMENT |
| LOW | requirements/ci.txt | 41 | pycparser==2.22 | COMMENT |
| LOW | requirements/ci.txt | 61 | pytest-xdist==3.6.1 | COMMENT |
| LOW | requirements/ci-3.11.txt | 1 | # | COMMENT |
| LOW | requirements/ci-3.11.txt | 21 | execnet==2.1.1 | COMMENT |
| LOW | requirements/ci-3.11.txt | 41 | pluggy==1.5.0 | COMMENT |
| LOW | requirements/ci-3.11.txt | 61 | pytest-socket==0.7.0 | COMMENT |
| LOW | requirements/ci-3.11.txt | 81 | # via -r requirements/ci.in | COMMENT |
| LOW | requirements/docs.txt | 1 | # | COMMENT |
| LOW | requirements/docs.txt | 21 | # via requests | COMMENT |
| LOW | requirements/docs.txt | 41 | # via sphinx | COMMENT |
| LOW | docs/conf.py | 141 | # To execute these examples real files need to be read and written. | COMMENT |
| LOW | pypdf/_encryption.py | 1 | # Copyright (c) 2022, exiledkingcc | COMMENT |
| LOW | pypdf/_writer.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/_reader.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/xmp.py | 41 | # It's documented here: https://github.com/adobe/xmp-docs/raw/master/XMPSpecifications/XMPSpecificationPart3.pdf | COMMENT |
| LOW | pypdf/_page.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/_doc_common.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/filters.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/filters.py | 121 | try: | COMMENT |
| LOW | pypdf/_utils.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/_utils.py | 521 | # | COMMENT |
| LOW | pypdf/_crypt_providers/_base.py | 1 | # Copyright (c) 2023, exiledkingcc | COMMENT |
| LOW | pypdf/_crypt_providers/_cryptography.py | 1 | # Copyright (c) 2023, exiledkingcc | COMMENT |
| LOW | pypdf/_crypt_providers/__init__.py | 1 | # Copyright (c) 2023, exiledkingcc | COMMENT |
| LOW | pypdf/_crypt_providers/_pycryptodome.py | 1 | # Copyright (c) 2023, exiledkingcc | COMMENT |
| LOW | pypdf/_crypt_providers/_fallback.py | 1 | # Copyright (c) 2023, exiledkingcc | COMMENT |
| LOW | pypdf/_text_extraction/_text_extractor.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/generic/_base.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/generic/_viewerpref.py | 1 | # Copyright (c) 2023, Pubpub-ZZ | COMMENT |
| LOW | pypdf/generic/__init__.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/generic/_image_inline.py | 1 | # Copyright (c) 2024, pypdf contributors | COMMENT |
| LOW | pypdf/generic/_data_structures.py | 1 | # Copyright (c) 2006, Mathieu Fenniak | COMMENT |
| LOW | pypdf/generic/_link.py | 1 | # All rights reserved. | COMMENT |
| LOW | pypdf/_codecs/adobe_glyphs.py | 1 | # https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt | COMMENT |
| LOW | pypdf/_codecs/adobe_glyphs.py | 21 | # provided with the distribution. | COMMENT |
| LOW | pypdf/_codecs/core_font_metrics.py | 1 | # This file is based upon the 14 core AFM files provided by Adobe/Macromedia at | COMMENT |
| LOW | pypdf/_codecs/_codecs.py | 181 | # https://github.com/empira/PDFsharp/blob/5fbf6ed14740bc4e16786816882d32e43af3ff5d/src/foundation/src/PDFsharp/src/P | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | pypdf/_writer.py | 0 | read-only boolean property showing whether this pdf file is encrypted. note that this property, if true, will remain tru | STRING |
| HIGH | pypdf/_reader.py | 0 | read-only boolean property showing whether this pdf file is encrypted. note that this property, if true, will remain tru | STRING |
| HIGH | pypdf/_doc_common.py | 0 | read-only boolean property showing whether this pdf file is encrypted. note that this property, if true, will remain tru | STRING |
| HIGH | pypdf/_writer.py | 0 | integration into jupyter notebooks. this method returns a dictionary that maps a mime-type to its representation. .. see | STRING |
| HIGH | pypdf/_reader.py | 0 | integration into jupyter notebooks. this method returns a dictionary that maps a mime-type to its representation. .. see | STRING |
| HIGH | pypdf/_doc_common.py | 0 | integration into jupyter notebooks. this method returns a dictionary that maps a mime-type to its representation. .. see | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | pypdf/_utils.py | 522 | # --------------------------------------------------------------------------------- | COMMENT |
| MEDIUM | pypdf/_utils.py | 550 | # --------------------------------------------------------------------------------- | COMMENT |
| MEDIUM | pypdf/_codecs/adobe_glyphs.py | 7 | # ----------------------------------------------------------- | COMMENT |
| MEDIUM | pypdf/_codecs/adobe_glyphs.py | 40 | # ----------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | pypdf/_codecs/core_font_metrics.py | 5 | # ----------------------------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | pypdf/_codecs/core_font_metrics.py | 14 | # ----------------------------------------------------------------------------------------------- | COMMENT |
| MEDIUM | pypdf/_codecs/_codecs.py | 185 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | pypdf/_codecs/_codecs.py | 210 | # -------------------------------------------------------------------------- | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pypdf/_writer.py | 562 | def set_need_appearances_writer(self, state: bool = True) -> None: | CODE |
| LOW | pypdf/_writer.py | 2354 | def _set_page_layout(self, layout: Union[NameObject, LayoutType]) -> None: | CODE |
| LOW | pypdf/_writer.py | 2390 | def set_page_layout(self, layout: LayoutType) -> None: | CODE |
| LOW | pypdf/__init__.py | 33 | __all__ = [ | CODE |
| LOW | pypdf/xmp.py | 683 | def _set_single_value(self, namespace: str, name: str, value: Optional[str]) -> None: | CODE |
| LOW | pypdf/xmp.py | 707 | def _set_bag_values(self, namespace: str, name: str, values: Optional[list[str]]) -> None: | CODE |
| LOW | pypdf/xmp.py | 735 | def _set_seq_values(self, namespace: str, name: str, values: Optional[list[str]]) -> None: | CODE |
| LOW | pypdf/xmp.py | 763 | def _set_langalt_values(self, namespace: str, name: str, values: Optional[dict[str, str]]) -> None: | CODE |
| LOW | pypdf/xmp.py | 796 | def _update_stream(self) -> None: | CODE |
| LOW | pypdf/_page.py | 132 | def _set_rectangle(self: Any, name: str, value: Union[RectangleObject, float]) -> None: | CODE |
| LOW | pypdf/_crypt_providers/__init__.py | 68 | __all__ = [ | CODE |
| LOW | pypdf/annotations/__init__.py | 28 | __all__ = [ | CODE |
| LOW | pypdf/_text_extraction/_layout_mode/__init__.py | 10 | __all__ = [ | CODE |
| LOW | …f/_text_extraction/_layout_mode/_text_state_manager.py | 51 | def set_state_param(self, op: bytes, value: Union[float, list[Any]]) -> None: | CODE |
| LOW | …f/_text_extraction/_layout_mode/_text_state_manager.py | 66 | def set_font(self, font: Font, size: float) -> None: | CODE |
| LOW | pypdf/actions/__init__.py | 13 | __all__ = [ | CODE |
| LOW⚡ | pypdf/generic/_viewerpref.py | 54 | def _set_bool(self, key: str, v: bool) -> None: | CODE |
| LOW⚡ | pypdf/generic/_viewerpref.py | 60 | def _set_name(self, key: str, lst: list[str], v: NameObject) -> None: | CODE |
| LOW⚡ | pypdf/generic/_viewerpref.py | 70 | def _set_arr(self, key: str, v: Optional[ArrayObject]) -> None: | CODE |
| LOW | pypdf/generic/_viewerpref.py | 84 | def _set_int(self, key: str, v: int) -> None: | CODE |
| LOW | pypdf/generic/__init__.py | 75 | __all__ = [ | CODE |
| LOW | pypdf/generic/_image_inline.py | 42 | logger = logging.getLogger(__name__) | CODE |
| LOW | pypdf/generic/_data_structures.py | 96 | logger = logging.getLogger(__name__) | CODE |
| LOW | pypdf/generic/_data_structures.py | 1036 | def set_data(self, data: bytes) -> None: | CODE |
| LOW | pypdf/generic/_data_structures.py | 1169 | def set_data(self, data: bytes) -> None: | CODE |
| LOW | pypdf/generic/_data_structures.py | 1510 | def set_data(self, data: bytes) -> None: | CODE |
| LOW | pypdf/_codecs/__init__.py | 45 | __all__ = [ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | make_release.py | 114 | git commit -eF RELEASE_COMMIT_MSG.md && git push | STRING |
| HIGH | make_release.py | 130 | git tag -eF RELEASE_TAG_MSG.md && git push | STRING |
| HIGH | tests/test_writer.py | 1750 | # "I DO NOT Agree": null, | COMMENT |
| HIGH | tests/test_filters.py | 713 | b"/DecodeParms [ null ]" | CODE |
| HIGH | pypdf/_page.py | 2459 | that is called 'FontFilex' (where x is null, 2, or 3), then that fontname is | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/test_reader.py | 1482 | # outline items (entitled Tables and Figures) utilize an empty action (/A) | COMMENT |
| LOW | pypdf/generic/_image_inline.py | 136 | # Ideally, we could just use plain run-length decoding here, where 80_16 = 128_10 | COMMENT |
| MEDIUM⚡ | pypdf/generic/_data_structures.py | 1760 | try: # Prefer to be more robust not only to null parameters | CODE |
| MEDIUM⚡ | pypdf/generic/_data_structures.py | 1765 | try: # Prefer to be more robust not only to null parameters | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/test_images.py | 61 | # Check if the images have the same dimensions | COMMENT |
| LOW | tests/test_images.py | 65 | # Check if the color modes are the same | COMMENT |
| LOW | tests/test_writer.py | 586 | # Check if the title was set | COMMENT |
| LOW | tests/test_merger.py | 129 | # Check if outline is correct | COMMENT |
| LOW | tests/bench.py | 100 | # Check if outline is correct | COMMENT |
| LOW | pypdf/_page.py | 713 | # Check if displayed (in content stream) | COMMENT |
| LOW | pypdf/generic/_data_structures.py | 345 | # Check if this is a chain list, we need to loop to prevent recur | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | pypdf/generic/_data_structures.py | 1291 | CODE | |
| MEDIUM | pypdf/generic/_data_structures.py | 1292 | CODE | |
| MEDIUM | pypdf/generic/_data_structures.py | 1293 | CODE | |
| MEDIUM | pypdf/generic/_data_structures.py | 1294 | CODE | |
| MEDIUM | pypdf/generic/_data_structures.py | 1295 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/utils.py | 127 | # Step 1: Count number of x- and y-coordinates of rectangles. | COMMENT |
| LOW | tests/utils.py | 150 | # Step 2: Look for texts in rectangles. | COMMENT |
| LOW | tests/utils.py | 164 | # Step 3: Build the list of rows containing list of cell-texts. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/utils.py | 127 | # Step 1: Count number of x- and y-coordinates of rectangles. | COMMENT |
| LOW | tests/utils.py | 150 | # Step 2: Look for texts in rectangles. | COMMENT |
| LOW | tests/utils.py | 164 | # Step 3: Build the list of rows containing list of cell-texts. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …f/_text_extraction/_layout_mode/_text_state_manager.py | 122 | CODE | |
| LOW | pypdf/generic/_appearance_stream.py | 342 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pypdf/_page_labels.py | 236 | # When there are no kids, make sure to exit the `while` loop directly | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pypdf/generic/_image_xobject.py | 478 | # TODO: implement mask | COMMENT |