pyhanko.sign.diff_analysis.commons module
Module defining common helpers for use by rules and policies.
In principle, these aren’t relevant to the high-level validation API.
- pyhanko.sign.diff_analysis.commons.qualify(level: pyhanko.sign.diff_analysis.policy_api.ModificationLevel, rule_result: typing.Generator[pyhanko.sign.diff_analysis.commons.X, None, pyhanko.sign.diff_analysis.commons.R], transform: typing.Callable[[pyhanko.sign.diff_analysis.commons.X], pyhanko.sign.diff_analysis.rules_api.ReferenceUpdate] = <function <lambda>>) Generator[Tuple[pyhanko.sign.diff_analysis.policy_api.ModificationLevel, pyhanko.sign.diff_analysis.rules_api.ReferenceUpdate], None, pyhanko.sign.diff_analysis.commons.R]
This is a helper function for rule implementors. It attaches a fixed modification level to an existing reference update generator, respecting the original generator’s return value (if relevant).
A prototypical use would be of the following form:
def some_generator_function(): # do stuff for ref in some_list: # do stuff yield ref # do more stuff return summary_value # ... def some_qualified_generator_function(): summary_value = yield from qualify( ModificationLevel.FORM_FILLING, some_generator_function() )
Provided that
some_generator_function
yieldsReferenceUpdate
objects, the yield type of the resulting generator will be tuples of the form(level, ref)
.- Parameters
level – The modification level to set.
rule_result – A generator that outputs references to be whitelisted.
transform – Function to apply to the reference object before appending the modification level and yielding it. Defaults to the identity.
- Returns
A converted generator that outputs references qualified at the modification level specified.
- pyhanko.sign.diff_analysis.commons.safe_whitelist(old: pyhanko.pdf_utils.reader.HistoricalResolver, old_ref, new_ref) Generator[pyhanko.pdf_utils.generic.Reference, None, None]
Checks whether an indirect reference in a PDF structure can be updated without clobbering an older object in a way that causes ramifications at the PDF syntax level.
The following are verified:
Does the old reference point to a non-stream object?
If the new reference is equal to the old one, does the new reference point to a non-stream object?
If the new reference is not equal to the old one, is the new reference a newly defined object?
This is a generator for syntactical convenience and integration with internal APIs, but it will always yield at most one element.
- pyhanko.sign.diff_analysis.commons.compare_key_refs(key, old: pyhanko.pdf_utils.reader.HistoricalResolver, old_dict: pyhanko.pdf_utils.generic.DictionaryObject, new_dict: pyhanko.pdf_utils.generic.DictionaryObject) Generator[pyhanko.pdf_utils.generic.Reference, None, Tuple[Optional[pyhanko.pdf_utils.generic.PdfObject], Optional[pyhanko.pdf_utils.generic.PdfObject]]]
Ensure that updating a key in a dictionary has no undesirable side effects. The following scenarios are allowed:
adding a key in new_dict
replacing a direct value in old_dict with a reference in new_dict
the reverse (allowed by default)
replacing a reference with another reference (that doesn’t override anything else)
The restrictions of safe_whitelist apply to this function as well.
Note: this routine is only safe to use if the structure of the resulting values is also checked. Otherwise, it can lead to reference leaks if one is not careful.
- pyhanko.sign.diff_analysis.commons.compare_dicts(old_dict: pyhanko.pdf_utils.generic.PdfObject, new_dict: pyhanko.pdf_utils.generic.PdfObject, ignored: Set[str] = frozenset({}), raise_exc=True) bool
Compare entries in two dictionaries, optionally ignoring certain keys.
- pyhanko.sign.diff_analysis.commons.assert_not_stream(obj)
Throw
SuspiciousModification
if the argument is a stream object.