§
    ¥”jÃ  ã                   óª  — d Z ddlZddlmZmZmZmZmZmZ ddl	m
Z
mZ ddlmZmZ ddlmZ ddlmZmZ dd	lmZ  ej        e¦  «        Zg d
¢Zeee
j                 ee
j                 f         Zd„ Zdedeeddf         fd„Zdede
j        de
j        deedef         fd„Z edd¬¦  «        Z edd¬¦  «        Z  ede¬¦  «        Z! eded¬¦  «        Z"dedee!def         deeee!f         def         fd„Z#dedee def         dee ge"f         deeee"f         def         fd„Z$ e%¦   «         dfdee         dee         d ee&         de'fd!„Z(dS )"z†
Module defining common helpers for use by rules and policies.

In principle, these aren't relevant to the high-level validation API.
é    N)ÚCallableÚ	FrozenSetÚ	GeneratorÚOptionalÚTupleÚTypeVar)ÚgenericÚmisc)Ú	PdfObjectÚ	Reference)ÚHistoricalResolveré   )ÚModificationLevelÚSuspiciousModification)ÚReferenceUpdate)Úassert_not_streamÚcompare_dictsÚcompare_key_refsÚqualifyÚqualify_transformingÚsafe_whitelistc                 ój   — t          | t          j        ¦  «        rt          d| j        › d�¦  «        ‚dS )zT
    Throw :class:`.SuspiciousModification` if the argument is a stream object.
    z!Unexpected stream encountered at ú!N)Ú
isinstancer	   ÚStreamObjectr   Úcontainer_ref)Úobjs    úq/var/www/finuniver-perm.ru/html/portfolio/venv/lib/python3.11/site-packages/pyhanko/sign/diff_analysis/commons.pyr   r      sF   € õ �#•wÔ+Ñ,Ô,ð 
Ý$ØD°Ô0AÐDÐDÐDñ
ô 
ð 	
ð
ð 
ó    ÚoldÚreturnc              #   ó  K  — |r!t          |                     ¦   «         ¦  «         ||k    r't          |                     ¦   «         ¦  «         |V — dS |                      |¦  «        r|V — dS t          d|› d�¦  «        ‚)a~  
    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.
    zUpdate clobbers or reuses z in an unexpected way.N)r   Ú
get_objectÚis_ref_availabler   )r    Úold_refÚnew_refs      r   r   r   )   sŸ   è è € ð( ð 0Ý˜'×,Ò,Ñ.Ô.Ñ/Ô/Ð/à�'ÒÐÝ˜'×,Ò,Ñ.Ô.Ñ/Ô/Ð/ØˆˆˆˆˆØ	×	Ò	˜gÑ	&Ô	&ð 
Øˆˆˆˆˆå$ØH¨ÐHÐHÐHñ
ô 
ð 	
r   Úold_dictÚnew_dictc              #   óð  K  — 	 |                      | ¦  «        }t          |t          j        ¦  «        r|j        }|                     ¦   «         }nd}n# t          $ r dx}}Y nw xY w	 |                      | ¦  «        }t          |t          j        ¦  «        r|j        }|                     ¦   «         }nd}n&# t          $ r |�t          d| › d�¦  «        ‚Y dS w xY w|�t          |||¦  «        E d{V —† ||fS )a¤  
    Ensure that updating a key in a dictionary has no undesirable side effects.
    The following scenarios are allowed:

    0. replacing a direct value with another direct value
    1. adding a key in new_dict
    2. replacing a direct value in old_dict with a reference in new_dict
    3. the reverse (allowed by default)
    4. 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.
    NzKey z was deleted from dictionary)NN)	Úraw_getr   r	   ÚIndirectObjectÚ	referencer#   ÚKeyErrorr   r   )Úkeyr    r'   r(   Ú	old_valueÚold_value_refÚ	new_valueÚnew_value_refs           r   r   r   K   sL  è è € ð0)Ø×$Ò$ SÑ)Ô)ˆ	Ý�i¥Ô!7Ñ8Ô8ð 	!Ø%Ô/ˆMØ!×,Ò,Ñ.Ô.ˆIˆIà ˆMøøÝð )ð )ð )Ø$(Ð(ˆ˜	˜	˜	ð)øøøðØ×$Ò$ SÑ)Ô)ˆ	Ý�i¥Ô!7Ñ8Ô8ð 	!Ø%Ô/ˆMØ!×,Ò,Ñ.Ô.ˆIˆIà ˆMøøÝð ð ð ØÐ Ý(Ø8�sÐ8Ð8Ð8ñô ð ð ˆzˆzðøøøð Ð Ý! # }°mÑDÔDÐDÐDÐDÐDÐDÐDÐDà�iÐÐs%   „AA ÁA#Á"A#Á'AB5 Â5CÃCÚRT)Ú	covariantÚ	QualifyIn)ÚcontravariantÚRefToUpd)ÚboundÚ	OutRefUpd)r8   r4   ÚlevelÚrule_resultc                 ó(   — t          | |d„ ¬¦  «        S )a¡  
    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:

    .. code-block:: python

        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`` yields
    :class:`~.generic.ReferenceUpdate` objects, the yield type of the resulting
    generator will be tuples of the form ``(level, ref)``.

    :param level:
        The modification level to set.
    :param rule_result:
        A generator that outputs references to be whitelisted.
    :return:
        A converted generator that outputs references qualified at the
        modification level specified.
    c                 ó   — | S ©N© )Úxs    r   ú<lambda>zqualify.<locals>.<lambda>±   s   € È€ r   )Ú	transform)r   )r:   r;   s     r   r   r   ‡   s   € õT    {¸k¸kÐJÑJÔJÐJr   rB   c                 ó8   ‡ ‡— t          j        |ˆ ˆfd„¦  «        S )a  
    This is a version of :func:`.qualify` that additionally allows
    a transformation to be applied to the output of the rule.

    :param level:
        The modification level to set.
    :param rule_result:
        A generator that outputs references to be whitelisted.
    :param transform:
        Function to apply to the reference object before appending
        the modification level and yielding it.
    :return:
        A converted generator that outputs references qualified at the
        modification level specified.
    c                 ó   •— ‰ ‰| ¦  «        fS r>   r?   )Úrefr:   rB   s    €€r   rA   z&qualify_transforming.<locals>.<lambda>É   s   ø€  %¨¨°3©¬Ð!8€ r   )r
   Úmap_with_return)r:   r;   rB   s   ` `r   r   r   ´   s-   øø€ õ( ÔØÐ8Ð8Ð8Ð8Ð8ñô ð r   Úignoredc           	      ód  — t          | t          j        ¦  «        st          j        d¦  «        ‚t          |t          j        ¦  «        st          d¦  «        ‚t          | ¦  «         t          |¦  «         t          |                     ¦   «         ¦  «        |z
  }t          |                      ¦   «         ¦  «        |z
  }||k    r|rt          d|› d|› d�¦  «        ‚dS |D ]O}| 	                    |¦  «        }|  	                    |¦  «        }||k    r|rt          d|› d|› d	|› �¦  «        ‚ dS ŒPd
S )zP
    Compare entries in two dictionaries, optionally ignoring certain keys.
    z?Encountered unexpected non-dictionary object in prior revision.z.Dict is overridden by non-dict in new revisionzDict keys differ: z vs. ú.FzValues for dict key z differ:z changed to T)
r   r	   ÚDictionaryObjectr
   ÚPdfReadErrorr   r   ÚsetÚkeysr*   )	r'   r(   rG   Ú	raise_excÚnew_dict_keysÚold_dict_keysÚkÚnew_valÚold_vals	            r   r   r   Í   s‹  € õ �h¥Ô 8Ñ9Ô9ð 
ÝÔØMñ
ô 
ð 	
õ �h¥Ô 8Ñ9Ô9ð 
Ý$Ø<ñ
ô 
ð 	
õ �hÑÔÐÝ�hÑÔÐÝ˜Ÿš™œÑ(Ô(¨7Ñ2€MÝ˜Ÿš™œÑ(Ô(¨7Ñ2€MØ˜Ò%Ð%Øð 	Ý(ØI ]ÐIÐI¸ÐIÐIÐIñô ð ð �5àð 
ð 
ˆØ×"Ò" 1Ñ%Ô%ˆØ×"Ò" 1Ñ%Ô%ˆØ�gÒÐØð Ý,ð6¨1ð 6ð 6Øð6ð 6Ø,3ð6ð 6ñô ð ð
 �u�uð ð ˆ4r   ))Ú__doc__ÚloggingÚtypingr   r   r   r   r   r   Úpyhanko.pdf_utilsr	   r
   Úpyhanko.pdf_utils.genericr   r   Úpyhanko.pdf_utils.readerr   Ú
policy_apir   r   Ú	rules_apir   Ú	getLoggerÚ__name__ÚloggerÚ__all__ÚTwoVersionsr   r   rJ   r   r3   r5   r7   r9   r   r   Ú	frozensetÚstrÚboolr   r?   r   r   ú<module>rd      sþ  ððð ð €€€Ø KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ Kà +Ð +Ð +Ð +Ð +Ð +Ð +Ð +Ø :Ð :Ð :Ð :Ð :Ð :Ð :Ð :Ø 7Ð 7Ð 7Ð 7Ð 7Ð 7à AÐ AÐ AÐ AÐ AÐ AÐ AÐ AØ &Ð &Ð &Ð &Ð &Ð &à	ˆÔ	˜8Ñ	$Ô	$€ðð ð €ð �H˜WÔ.Ô/°¸'Ô:KÔ1LÐLÔM€ð
ð 
ð 
ð
Ø	ð
àˆy˜$ Ð$Ô%ð
ð 
ð 
ð 
ðD3 à	ð3 ð Ô&ð3 ð Ô&ð	3 ð
 ˆy˜$ Ð+Ô,ð3 ð 3 ð 3 ð 3 ðl €GˆC˜4Ð Ñ Ô €ØˆG�K¨tÐ4Ñ4Ô4€	Øˆ7�: _Ð5Ñ5Ô5€ØˆG�K À$ÐGÑGÔG€	ð*KØð*Kà˜8 T¨1Ð,Ô-ð*Kð ˆuÐ&¨Ð0Ô1°4¸Ð:Ô;ð*Kð *Kð *Kð *KðZØðà˜9 d¨AÐ-Ô.ðð ˜˜ YÐ.Ô/ðð ˆuÐ&¨	Ð1Ô2°D¸!Ð;Ô<ð	ð ð ð ð8 (˜i™kœkØð	+ð +Ø�yÔ!ð+à�yÔ!ð+ð �sŒ^ð+ð
 
ð+ð +ð +ð +ð +ð +r   