
    Wwg                        d Z ddlZddlZddlZddlmZmZmZmZmZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZ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 ddlmZm Z m!Z!m"Z"m#Z# ddl$m%Z% ddl&m'Z'm(Z(m)Z)m*Z*m+Z+ ejX                  rddl-m.Z. g dZ/ ej`                  e1      Z2	 d de3deejh                     dejj                  fdZ6 G d de%      Z7 G d dejh                        Z8 G d de7      Z9 G d d      Z:	 d de%dee;   de9fdZ<y)!z
Utilities for writing PDF files.
Contains code from the PyPDF2 project; see :ref:`here <pypdf2-license>`
for the original license.
    N)DictIterableListOptionalSetTupleUnioncast)x509)generic)PubKeySecurityHandlerSecurityHandlerStandardSecurityHandler)DeveloperExtensionDevExtensionMultivalued)pdf_name)update_info_dictview_from_info_dict)DocumentMetadata)IndirectObjectExpectedPdfErrorPdfReadErrorPdfWriteErrorinstance_test)
PdfHandler)OBJSTREAM_FORBIDDENObjectStreamPositionDict
XRefStreamwrite_xref_table   FontSubsetCollection)BasePdfFileWriter
PageObjectPdfFileWriterinit_xobject_dictionarycopy_into_new_writercommand_stream	resourcesreturnc                 L   |xs t        j                         }t        j                  t        d      t        j                  t        t        t         j                  d||df                  t        d      |t        d      t        d      t        d      t        d      i|       S )	a  
    Helper function to initialise form XObject dictionaries.

    .. note::
        For utilities to handle image XObjects, see :mod:`.images`.

    :param command_stream:
        The XObject's raw appearance stream.
    :param box_width:
        The width of the XObject's bounding box.
    :param box_height:
        The height of the XObject's bounding box.
    :param resources:
        A resource dictionary to include with the form object.
    :return:
        A :class:`~.generic.StreamObject` representation of the form XObject.
    /BBoxg        
/Resources/Type/XObject/Subtype/Formstream_data)r   DictionaryObjectStreamObjectr   ArrayObjectlistmapFloatObject)r)   	box_width
box_heightr*   s       O/var/www/horilla/myenv/lib/python3.12/site-packages/pyhanko/pdf_utils/writer.pyr'   r'   =   s    . 7W557IWw22++c:y#-NO 
 \"IWx
3Z (7"3		
 #     c                      e Zd ZU dZdZ	 eed<   	 	 	 d=deej                  ej                  f   deej                  ej                  df   dej                  dedef
d	Zd
efdZedefd       Zedefd       Zd Zdeej                  ej                  df   deej                     fdZdej.                  dej0                  fdZedeeef   fd       Zdeej:                  ej                  f   fdZdej0                  fdZedej:                  fd       Z d Z!de"fdZ#d>defdZ$dej                  fdZ%	 d?d ee&   dej                  fd!Z'd@d"Z(d# Z)d$e*fd%Z+d&e&fd'Z,d(e-fd)Z.d* Z/d+ Z0d, Z1edej                  fd-       Z2ed.        Z3d/ Z4dAd0efd1Z5d>d2efd3Z6d4 Z7dBd5Z8	 dBdej0                  d ee&   dej0                  fd6Z9	 d=d7e:fd8Z;	 dCd9Z<d:ej                  d;ej                  defd<Z=y)Dr$   zBase class for PDF writers.)r!      stream_xrefsrootinfoNdocument_idobj_id_startc                 <   i | _         t               | _        i | _        || _        | f| _        t               | _        t        |t        j                        r|| _        n| j                  |      | _        d | _        d | _        d | _        || _        || _        d }|Wt        |t        j                        s| j                  |      }n+t        j                  |j$                  |j&                  |       }|| _        t+               | _        i | _        d| _        d | _        y NF)objectsr8   object_streamsobjs_in_streams_lastobj_id_resolves_objs_fromset_allocated_placeholders
isinstancer   IndirectObject_root
add_objectsecurity_handler_encrypt_encrypt_key_document_idrA   idnum
generation_infor   _meta_font_resourcesdigest_aware_write_mac_handler_cls)selfrB   rC   rD   rE   rA   info_refs          r=   __init__zBasePdfFileWriter.__init__t   s     BD26&=?':> 14$dG223DJ.DJ;?:>-1'(dG$:$:;??40"11JJ 
'7'9
BD"' $r>   base_postscript_namec                     ddl m} 	 | j                  |   }|S # t        $ r  ||      }|| j                  |<   Y |S w xY w)Nr!   r"   )font.apir#   r[   KeyError)r^   ra   r#   fscs       r=   get_subset_collectionz'BasePdfFileWriter.get_subset_collection   sT    2	=&&';<C
 
	  	=&';<C9<D  !56
		=s     ==r+   c                     | j                   S N)rZ   r^   s    r=   document_metazBasePdfFileWriter.document_meta   s    zzr>   c                     | j                   r$t        | j                   j                               }n
t               }| j                  j                  |      S rh   )rY   r   
get_objectr   rZ   	view_over)r^   bases     r=   document_meta_viewz$BasePdfFileWriter.document_meta_view   s?     ::&tzz'<'<'>?D#%Dzz##D))r>   c                 2    | j                   |k  r|| _         y y rh   )output_version)r^   versions     r=   ensure_output_versionz'BasePdfFileWriter.ensure_output_version   s    (")D )r>   c                     |4t        |t        j                        s| j                  |      x| _        }|S |x| _        }|S )z
        Set the ``/Info`` entry of the document trailer.

        :param info:
            The new ``/Info`` dictionary, as an indirect reference.
        )rO   r   rP   rR   rY   )r^   rC   new_infos      r=   set_infozBasePdfFileWriter.set_info   sH     JtW5K5K$L$(OOD$99DJ  %)(DJr>   keyvaluec                     t         )  
        Set a custom, unmanaged entry in the document trailer or cross-reference
        stream dictionary.

        .. warning::
            Calling this method to set an entry that is managed by pyHanko
            internally (info dictionary, document catalog, etc.) has undefined
            results.

        :param key:
            Dictionary key to use in the trailer.
        :param value:
            Value to set
        NotImplementedErrorr^   rw   rx   s      r=   set_custom_trailer_entryz*BasePdfFileWriter.set_custom_trailer_entry   s
    " "!r>   c                 V    | j                   }|d   j                  |d   j                  fS )Nr   r!   )rV   original_bytes)r^   id_arrs     r=   rD   zBasePdfFileWriter.document_id   s,    ""ay'')A)AAAr>   obj_refc                      y)a  
        Mark an object reference to be updated.
        This is only relevant for incremental updates, but is included
        as a no-op by default for interoperability reasons.

        :param obj_ref:
            An indirect object instance or a reference.
        N )r^   r   s     r=   mark_updatezBasePdfFileWriter.mark_update   s     	r>   objc                      y)a  
        Mark the container of an object (as indicated by the
        :attr:`~.generic.PdfObject.container_ref` attribute on
        :class:`~.generic.PdfObject`) for an update.

        As with :meth:`mark_update`, this only applies to incremental updates,
        but defaults to a no-op.

        :param obj:
            The object whose top-level container needs to be rewritten.
        Nr   )r^   r   s     r=   update_containerz"BasePdfFileWriter.update_container   s     	r>   c                 .    | j                   j                  S )zK
        :return:
            A reference to the document catalog.
        )rQ   	referenceri   s    r=   root_refzBasePdfFileWriter.root_ref   s     zz###r>   c                      y)z
        Signal that the document catalog should be written to the output.
        Equivalent to calling :meth:`mark_update` with :attr:`root_ref`.
        Nr   ri   s    r=   update_rootzBasePdfFileWriter.update_root  s    
 	r>   extc           
         	 | j                   d   }	 |j	                  |j
                  t        j                  j                        }d}d}t        |t        j                        r|f}nNt        |t        j                        rt        |      }d}n&|$t        |      j                  }t        d| d      t        |      D ]  \  }}t        |t        j                        s$t        |      j                  }t        d| d	      	 t        |j	                  d
            }	|	|j$                  k(  r y |j&                  r|	|j$                  k\  }
|
 }n|	|j(                  v }
|	|j*                  v }|
r y |r|r|j-                         ||<   nl|j.                  t0        j2                  k(  r2t        j                  |j-                         g      ||j
                  <   n|j-                         ||j
                  <   | j5                  |        y |j.                  t0        j6                  k(  sft9        d|j
                   d|j$                   d|	 d       |j-                         }|Q|j.                  t0        j2                  k(  r$t        j                  |g      ||j
                  <   nH|||j
                  <   n8|r|j;                  |       n$t        j                  ||g      ||j
                  <   | j5                  |       y # t        $ r' t        j                         x| j                   d<   }Y w xY w# t        $ r d }Y w xY w# t         t"        t        f$ r t        d      w xY w)Nz/Extensionsdecryptr   FTzPDF extension value is of type z,, expected (direct) PDF dictionary or array.z%PDF extension array entry is of type z", expected (direct) PDF dictionaryz/ExtensionLevelz(Could not read developer extension levelz)Could not register extension with prefix z and level z?; file contains extension with same prefix and extension level zC. If this extension level is safe to override, mark it as subsumed.)rB   rd   r   r5   raw_getprefix_nameEncryptedObjAccessRAWrO   r7   tupletype__name__r   	enumerateint	TypeError
ValueErrorextension_levelcompare_by_levelsubsumed_bysubsumesas_pdf_objectmultivaluedr   ALWAYSr   NEVERr   append)r^   r   
extensionscur_ext_valueextension_dictsold_ext_multivaluedcls_nameixext_dictlvlold_ext_appliesreplace_olds               r=   register_extensionz$BasePdfFileWriter.register_extension  s`   	O=1J
	!&..)C)C)G)G / M
 8:#mW%=%=>,.Ow':':;#M2O"&&M*33H1( <= >  &o6 2	LBh(@(@A>22";j BD O(**+<=>
 c)))%%"%)<)<"<"11 #&"8!S\\1 ' ),(9(9(;M"%__(?(F(FF 3:2E2E**,-3Js/ 362C2C2EJs/%%j1$;$A$AA $?'{33F3F2G H''*e ,=> Y2	j $$& "9"@"@@.5.A.A8*.M
3??+.6
3??+"$$X. /6.A.A"H-/
3??+ 	j)A  	O4;4L4L4NNDIIm$z	O  	! M	!8 z84 O"#MNNOs.   K? 5L2 M?,L/.L/2M M M$as_metadata_streamc                 |   |j                   | j                  vrt        d| d      |j                  }|j                  }	 | j
                  ||f   S # t        $ r` |dk(  rO|| j                  v rt        j                         cY S 	 | j                  |   cY S # t        $ r Y t        |      w xY wt        |      w xY w)Nz
Reference z$ has no relation to this PDF writer.r   )pdfrL   r   rW   rX   rH   rd   rN   r   
NullObjectrJ   )r^   idor   rW   rX   s        r=   rl   zBasePdfFileWriter.get_objectt  s    77$222SE!EF  		^^

	 <<U 344 	 QD888"--////66 3-3-	 s0   A 0B;BB;	B,B;+B,,B;c                     | j                   dz   }| j                  j                  |       | xj                   dz  c_         t        j                  |d|       S )a(  
        Allocate an object reference to populate later.
        Calls to :meth:`get_object` for this reference will
        return :class:`~.generic.NullObject` until it is populated using
        :meth:`add_object`.

        This method is only relevant in certain advanced contexts where
        an object ID needs to be known before the object it refers
        to can be built; chances are you'll never need it.

        :return:
            A :class:`~.generic.IndirectObject` instance referring to
            the object just allocated.
        r!   r   )rK   rN   addr   rP   )r^   rW   s     r=   allocate_placeholderz&BasePdfFileWriter.allocate_placeholder  sN        1$$$((/A%%eQ55r>   
obj_streamc                    ||| j                   vrt        d      d}nd}| j                  dz   }||| j                  d|f<   nH|| j                  v r"|j                  ||       || j                  |<   nt        dt        |       d      |r| j                   j                  |       n| xj                  dz  c_        t        j                  |d|       S )a  
        Add a new object to this writer.

        :param obj:
            The object to add.
        :param obj_stream:
            An object stream to add the object to.
        :param idnum:
            Manually specify the object ID of the object to be added.
            This is only allowed for object IDs that have previously been
            allocated using :meth:`allocate_placeholder`.
        :return:
            A :class:`~.generic.IndirectObject` instance referring to
            the object just added.
        zkManually specifying idnum is only allowed for references previously allocated using allocate_placeholder().TFr!   r   zStream z is unknown to this PDF writer.)rN   r   rK   rH   rI   rR   rJ   reprremover   rP   )r^   r   r   rW   preallocateds        r=   rR   zBasePdfFileWriter.add_object  s    & D888#. 
  L L$$q(E'*DLL!U$4...!!%-*-D  '$z*++JK  ((//6!%%eQ55r>   c                     | j                   st        d      t        |      }| j                  j	                  |       |S )zPrepare and return a new :class:`.ObjectStream` object.

        :param compress:
            Indicates whether the resulting object stream should be compressed.
        :return:
            An :class:`.ObjectStream` object.
        z2Object streams require Xref streams to be enabled.)compress)rA   r   r   rI   r   )r^   r   streams      r=   prepare_object_streamz'BasePdfFileWriter.prepare_object_stream  sB       D  x0""6*r>   c                     t         rh   r{   )r^   r   s     r=   _write_headerzBasePdfFileWriter._write_header  s    !!r>   shc                     || _         | j                  |j                               | _        |j	                         }|| j                  |       | j                   j                         D ]  }| j                  |        y rh   )rS   rR   r   rT   get_min_pdf_versionrs   get_extensionsr   )r^   r   min_pdf_version	extensions       r=   _assign_security_handlerz*BasePdfFileWriter._assign_security_handler  sq     "(8(8(:;002&&&7..==? 	/I##I.	/r>   obj_stmc              #      K   |j                   }|r(|s&| j                  |j                               x|_         }t        |      D ]  \  }\  }}||j                  |ff  yw)zh
        Internal method to flush an object stream as part of the file
        writing process.
        N)refrR   r   r   rW   )r^   r   
stream_refr   rW   r   s         r=   _flush_obj_streamz#BasePdfFileWriter._flush_obj_stream  sk     
 [[
: (,w7L7L7N'OOGK* !*' 2 	0B***B///	0s   A A"object_position_dictc                 F   | j                   D ]"  }| j                  |      D ]  \  }}||d|f<    $ t        | j                  j	                               D ]  }|\  }}| j                  |   }|j                         ||<   |j                  d||fz  j                  d             d }	| j                  3| j                  J || j                  j                  k7  r| j                  }	t        j                  |||       }
|j                  ||	|
       |j                  d        y )Nr   
%d %d obj
ascii   
endobj
)rI   r   sortedrH   keystellwriteencoderS   rT   rW   r   	Referencewrite_to_stream)r^   r   r   r   rW   
pos_recordr   rX   r   handlercontainer_refs              r=   _write_objectsz BasePdfFileWriter._write_objects  s"   -- 	>J%)%;%;J%G >!z3=$aZ0>	> **,- 	(B "J,,r"C'-{{} $LL-5**==EEgNO15G$$0}}000DMM///"33G#--eZFM?LL'	(r>   c                     | j                   j                         D ]1  }|j                  j                         D ]  }|j                           3 | j	                          y rh   )r[   valuessubsetsprepare_write_update_meta)r^   re   engines      r=   _prep_dom_for_writingz'BasePdfFileWriter._prep_dom_for_writing
  sV    ''..0 	'C++,,. '$$&'	' 	r>   c                 p   d }	 ddl m} | j                  j                  xs@ t	        | j                  j
                        xs | j                  dk\  xs d| j                  v }d| j                  _	        | j                  Nt        | j                  | j                  j                         |      }|r^| j                  | j                         nB|s@t        j                         }t        | j                  |       | j!                  |      | _
        |rd }d| j                  v rS| j                  d   }t#        ||j$                        r.|}|j'                  | j                         | j)                  |       ||j$                  j+                  |j'                  | j                              }| j,                  }||_        |&| j,                  j0                  s|j3                          | j!                  |      | j                  d<   | j5                          | j5                          y y # t        $ r d}Y w xY w)Nr   xmp_xml   r   	/MetadataFnow)only_update_existing)pyhanko.pdf_utils.metadatar   rZ   xmp_unmanagedbool	xmp_extrarq   rB   ImportErrorlast_modifiedrY   r   rl   r   r   r5   rR   rO   MetadataStreamupdate_xmp_with_metar   from_xmprS   _handlerencrypt_metadataadd_crypt_filterr   )r^   r   need_xmpmod	info_dictmeta_stmmeta_objr   s           r=   r   zBasePdfFileWriter._update_meta  s   	
 ; 

(( ,

,,-,&&&0, $))+	  $)

 ::!"



%%'%-	C   ,002ITZZ33DJ Hdii'99[1h(>(>?'H11$**=))(3"11::00< **$&!N 11BB --/)-)B		+&  "/ )  	H	s   AH& &H54H5c                     | j                   |t        d      <   | j                  | j                  |t        d      <   | j                  | j                  |t        d      <   | j                  |t        d      <   y )Nz/Root/Infoz/Encryptz/ID)rQ   r   rY   rT   rV   r^   trailers     r=   _populate_trailerz#BasePdfFileWriter._populate_trailerN  se    %)ZZ!"::!)-GHW%&==$,0MMGHZ() $(#4#4 r>   c                 P    t        j                         }| j                  |       |S rh   )r   r5   r  r  s     r=   trailer_viewzBasePdfFileWriter.trailer_viewY  s#    **,w'r>   c                 l    | j                    xr& | j                  d uxr | j                  j                  S rh   )r\   rS   pdf_mac_enabledri   s    r=   _need_mac_on_writez$BasePdfFileWriter._need_mac_on_write_  s<     ''' 6%%T16%%55	
r>   c                     | j                          | j                  r5ddlm} | j	                  |j
                         |j                  | |       y| j                  |       y)z
        Write the contents of this PDF writer to a stream.

        :param stream:
            A writable output stream.
        r   pdfmac)outputN)r   r	  pyhanko.pdf_utils.cryptr  r   ISO32004add_standalone_mac_write)r^   r   r  s      r=   r   zBasePdfFileWriter.writeg  sM     	""$""6##FOO4%%d6%:KKr>   md_algorithmc                     ddl m} | j                  xs |j                  }| j                  }|J |j                  |j                         |j                         |      S )zL
        MAC-adding method that can easily be manipulated in tests.
        r   r  )file_encryption_keykdf_saltr  )r  r  r]   PdfMacTokenHandlerrS   from_key_matget_file_encryption_keyget_kdf_salt)r^   r  r  clsr   s        r=   _init_mac_handlerz#BasePdfFileWriter._init_mac_handlerw  sc     	3##@v'@'@""~~ " : : <__&%   
 	
r>   skip_headerc           	         i }| j                   rt        |      }|j                          |}nt        j                         }|s| j                  |       | j                  |       | j                  ||       | j                   r|j                         }| j                  dz   }||d|f<   t        j                  |dz         |t        d      <   |j                  d|dfz  j                  d             |j                  |d        |j                  d       nt        |t!        t"        t$        t&        t&        f   t&        f   |            }t        j                  | j                  dz         |t        d      <   |j                  d       |j                  |d        d|z  }|j                  |j                  d      d	z          y )
Nr!   r   z/Sizer   r   r   s   trailer
z
startxref
%s
s   %%EOF
)rA   r   r   r   r5   r   r  r   r   rK   NumberObjectr   r   r   r   r    r
   r   r   r   )	r^   r   r  object_positionsxmp_trailerr  xref_locationxrefs_idxref_pointer_strings	            r=   r  zBasePdfFileWriter._write  s   )+ $%56K  "!G..0Gv&w'F$45"KKMM''!+H.;a]+)0)=)=hl)KGHW%&LL-8Q-7??HI##FD1LL' -T%S/3"679IJM *1)=)=  1$*GHW%& LL&##FD1 2MA(//8:EFr>   c                    |j                         }	 |j                  d      }t        |t        j                        r"|j                         }| j                  |       n|}| j                  |       |j                  |       y# t        $ r6 t        j                         }| j                  |       ||t        d      <   Y Pw xY w)aG  
        Register an annotation to be added to a page.
        This convenience function takes care of calling :meth:`mark_update`
        where necessary.

        :param page_ref:
            Reference to the page object involved.
        :param annot_ref:
            Reference to the annotation object to be added.
        z/AnnotsN)
rl   r   rO   r   rP   r   rd   r7   r   r   )r^   page_ref	annot_refpage_objannot_arr_refannotss         r=   register_annotationz%BasePdfFileWriter.register_annotation  s     &&(	3$,,Y7M-)?)?@&113  / '  * 	i   	3((*FX&,2HXi()	3s   A B <CCc                    |d   t        d      k7  rt        d      d|v rt        d      | j                  j                  d      }||j	                         d   }|dz
  }|d	k(  r|}d	}n| j                  |      \  }}}|j	                         }	 |d
   }	|}
|
=|
d   }t        j                  |dz         |
t        d      <   |
j                  d      }
|
=| j                  |      }|	j                  |dz   |       ||t        d      <   | j                  |       | j                  |	       |S # t        $ r t        d      w xY w)a  
        Insert a page object into the tree.

        :param new_page:
            Page object to insert.
        :param after:
            Page number (zero-indexed) after which to insert the page.
        :return:
            A reference to the newly inserted page.
        r/   /PagezNot a page object/Parentz/Parent must not be set./Pages/Countr!   /Kidsz/Pages must have /Kids)r   r   rB   r   rl   find_page_containerrd   r   r   r  getrR   insertr   )r^   new_pageafterpage_tree_root_ref
page_countpages_obj_refkid_ix_	pages_objkidsparentcountnew_page_refs                r=   insert_pagezBasePdfFileWriter.insert_page  sl    G 11 344  :;;!YY..x8=+668BJNEB;.MF'+'?'?'F$M61!,,.		5W%D
  8$E)0)=)=eai)HF8H%&ZZ	*F	  
 x0FQJ-(5)$%i(d#!  	5344	5s   D/ /Ec                 z    t        |j                         j                         | |i       }|j                  |      S )a  
        Deep-copy an object into this writer, dealing with resolving indirect
        references in the process.

        .. danger::
            The table mapping indirect references in the input to indirect
            references in the writer is not preserved between calls.
            Concretely, this means that invoking :meth:`import_object` twice
            on the same input reader may cause object duplication.

        :param obj:
            The object to import.
        :param obj_stream:
            The object stream to import objects into.

            .. note::
                Stream objects and bare references will not be put into
                the object stream; the standard forbids this.
        :return:
            The object as associated with this writer.
            If the input object was an indirect reference, a dictionary
            (incl. streams) or an array, the returned value will always be
            a new instance.
        )sourcetargetr   reference_map)_ObjectImporterget_container_refget_pdf_handlerimport_object)r^   r   r   importers       r=   rI  zBasePdfFileWriter.import_object  s?    8 #((*::<!	
 %%c**r>   otherc           
         |j                  |      \  }}|j                         }|}	 	 |d   }	 t	        d      |t	        d      | j                  |      t	        d      t	        d      t	        d	      t	        d
      i}	|d   }
t        |
t        j                        rrt        |
      dk(  r|r|
d   j                         }
nNt        j                  |	dj                  d |
D                    }|j                          | j                  |      S t        |
t        j                        sJ d}|r	 |
d   }|?| j                  |      |	t	        d      <   t        j                  |	|
j                        }n!t        j                  |	|
j                        }| j                  |      S # t        $ r& 	 |d   }n# t        $ r t        d| d      w xY wY nw xY w# t        $ r Y w xY w)a  
        Import a page content stream from some other
        :class:`~.rw_common.PdfHandler` into the current one as a form XObject.

        :param other:
            A :class:`~.rw_common.PdfHandler`
        :param page_ix:
            Index of the page to copy (default: 0)
        :param inherit_filters:
            Inherit the content stream's filters, if present.
        :return:
            An :class:`~.generic.IndirectObject` referring to the page object
            as added to the current reader.
        	/MediaBoxr-  zPage z does not have a /MediaBoxr-   r.   r/   r0   r1   r2   	/Contentsr!   r   r>   c              3   P   K   | ]  }|j                         j                     y wrh   )rl   data).0partial_streams     r=   	<genexpr>z;BasePdfFileWriter.import_page_as_xobject.<locals>.<genexpr>V  s'      )* '11388)s   $&r3   Nz/Filterencoded_data)find_page_for_modificationrl   rd   r   r   rI  rO   r   r7   lenr6   joinr   rR   rU  rP  )r^   rK  page_ixinherit_filtersr%  r*   r'  pagetree_objmbstream_dictr)   resultfilterss                r=   import_page_as_xobjectz(BasePdfFileWriter.import_page_as_xobject"  s   " $>>wG)&&(  	!+. Wr\"D$6$6y$AWx
3Z (7"3	
 "+. ng&9&9:>"a'O!/!2!=!=!?
 !-- # ).<) ! !v...'*>*>???(3 /3/A/A'/JK+,)).*E*EF )))<)<F v&&i  #/	#:L &y(BC  !	 V  s;   F( 0G (	G2F87G8GGG	G('G(c                    | j                  |      \  }}|j                         }|j                  d      }t        |t        j
                        r|j                         }	t        |	t        j                        r9| j                  |       |r|	j                  d|       n|	j                  |       nt        |	t        j                        rN|r||gn||g}
t	        j                  |
      }	| j                  |	      |t        d      <   | j                  |       nt        d      t        |t        j                        rW|}	|r|	j                  d|       n|	j                  |       | j                  |	      |t        d      <   | j                  |       nt        d      |yt        |t        j
                        rQ|j                         }t        |t        j                        sJ | j                  ||      r| j                  |       |S t	        j                  |      }| j                  |      |t        d      <   | j                  ||       |S )ae  Append an indirect stream object to a page in a PDF as a content
        stream.

        :param page_ix:
            Index of the page to modify.
            The first page has index `0`.
        :param stream_ref:
            :class:`~.generic.IndirectObject` reference to the stream
            object to add.
        :param resources:
            Resource dictionary containing resources to add to the page's
            existing resource dictionary.
        :param prepend:
            Prepend the content stream to the list of content streams, as
            opposed to appending it to the end.
            This has the effect of causing the stream to be rendered
            underneath the already existing content on the page.
        :return:
            An :class:`~.generic.IndirectObject` reference to the page object
            that was modified.
        rN  r   z"Unexpected type for page /ContentsNr.   )rV  rl   r   rO   r   rP   r7   r   r4  r   r6   rR   r   r   r5   merge_resources)r^   rY  r   r*   prependpage_obj_refres_refr'  contents_refcontentsneworig_resource_dicts               r=   add_stream_to_pagez$BasePdfFileWriter.add_stream_to_pages  s   2 !% ? ? Hg**,''4lG$:$:;#..0H(G$7$78   .OOAz2OOJ/Hg&:&:;
   .&
3 
 #..s326//(2K+./  .CDDg&9&9:#H:.
+.2ooh.GHXk*+\*?@@gw556!(!3!3!50'2J2JKKK##$6	B  )  ")!9!9'!B/3"0HXl+,   !3Y?r>   	orig_dictnew_dictc           	      :  	 d}|j                         D ]  \  }}	 |j                  |      }t        |t        j
                        r"|j                         	| j                  |       n|	d}t        	t        j                        r.|dk(  r)	j                  	fd|j                         D               t        	t        j                        s|j                         D ]   \  }}|	v rt        d|d|d      |	|<   "  |S # t        $ r d}|||<   Y w xY w)a  
        Update an existing resource dictionary object with data from another
        one. Returns ``True`` if the original dict object was modified directly.

        The caller is responsible for avoiding name conflicts with existing
        resources.
        FTz/ProcSetc              3   ^   K   | ]$  }t        |t        j                        r|vr| & y wrh   )rO   r   
NameObject)rQ  x
orig_values     r=   rS  z4BasePdfFileWriter.merge_resources.<locals>.<genexpr>  s0      "!!W%7%78Qj=P "s   *-z$Naming conflict in resource of type z: key z occurs in both.)itemsr   rd   rO   r   rP   rl   r   r7   extendr5   r   )
r^   rk  rl  update_neededrw   rx   orig_value_refkey_value_rq  s
            @r=   rb  z!BasePdfFileWriter.merge_resources  s1    "..* 	.JC!*!2!23!7 .'*@*@A+668
  0+
 $ :w':':;:%!! ""--/" 
 J(@(@A$)KKM .LD&z)&8;TC  (.Jt$.3	.B =   $!&	#s   DDD)r   T)F)NN)T)sha256rh   rG   )>r   
__module____qualname____doc__rq   r   __annotations__r	   r   rP   r5   r7   r   r`   strrf   propertyr   rj   ro   rs   r   rv   ro  	PdfObjectr~   r   bytesrD   r   r   r   r   r   r   r   rl   r   r   rR   r   r   r   r   r   r   r   r   r   r  r  r	  r   r  r  r*  rA  rI  r   r`  rj  rb  r   r>   r=   r$   r$   d   s*   %N; !&%G**G,D,DDE&% G**G,D,DdJK&% ((	&%
 &% &%P	# 	 /   
*$4 
* 
**G**G,D,DdJK 
'((	)""%%".5.?.?"& BU5%<0 B BW..0F0FFGG$5$5  $'++ $ $c*&8 c*J $  &6g&<&< 6, EI-6'5-6			-6^ "/? /0 0(< ((:x	5 g66  
 
 
  
c 
(G$ (GT!:/d LP"+$$"+2:<2H"+			"+J =AN'N'd <AUp/++/ **/ 
	/r>   r$   c                   $     e Zd ZdZd fd	Z xZS )r%   zySubclass of :class:`~.generic.DictionaryObject` that handles some of the
    initialisation boilerplate for page objects.c                 ~   |xs t        j                         }t        |t              rgt	        t        t        t         j                        |            st        d      t        |t         j                        s;t        j                  |      }n%t        |t         j                        st        d      t        |      dk7  rt        d      t        | 5  t        d      t        d      t        d      t        j                  t        t         j                  |            t        d      |t        d	      |i       y )
Nz2Contents array must consist of indirect referencesz9Contents must be either an indirect reference or an array   z(Media box must consist of 4 coordinates.r/   r,  rM  r.   rN  )r   r5   rO   r8   allr9   r   rP   r   r7   rW  r   superr`   r   r:   )r^   rg  	media_boxr*   	__class__s       r=   r`   zPageObject.__init__  s   ;!9!9!;	h%s=)?)?@(KL#H  h(;(;<"..x8Hg&<&<=K  y>QGHH!8G#4%w':':++Y7( &	%x		
r>   rh   )r   ry  rz  r{  r`   __classcell__r  s   @r=   r%   r%     s    4
 
r>   r%   c                        e Zd ZdZd fd	Zd ZddZdeej                     fdZ
dej                  dej                  fd	Z fd
Z xZS )r&   zClass to write new PDF files.c           	      b   t        j                  t        d      t        d      i      }t        j                  t	        j
                  d            }t        j                  t	        j
                  d            }t        j                  ||g      }i | _        t        	| %  ||||       |rt        j                  t        d      t        d      t        d      t        j                  d      t        d      t        j                         i      }| j                  |      |t        d      <   y y )	Nr/   z/Catalog   )rA   r.  r/  r   r1  )r   r5   r   ByteStringObjectosurandomr7   _custom_trailer_entriesr  r`   r  rR   )
r^   rA   init_page_treerC   rB   id1id2id_objpagesr  s
            r=   r`   zPdfFileWriter.__init__$  s    ''!8J#7
 &&rzz"~6&&rzz"~6$$c3Z0')$tV,G,,W%x'9X&(<(<Q(?W%w':':'<E (,u'=D(#$ r>   c                     | j                   \  }}|j                  d| d| dj                  d             |j                  d       y )Nz%PDF-.
r   s   %¥±ë
)rq   r   r   )r^   r   majorminors       r=   r   zPdfFileWriter._write_header>  sF    **uuUG1UG2.55g>? 	34r>   c                 T    t        j                  ||fi |}| j                  |       y)a>  
        Mark this document to be encrypted with PDF 2.0 encryption (AES-256).

        .. caution::
            While pyHanko supports legacy PDF encryption as well, the API
            to create new documents using outdated encryption is left
            largely undocumented on purpose to discourage its use.

            This caveat does *not* apply to incremental updates added to
            existing documents.

        .. danger::
            The PDF 2.0 standard mandates AES-256 in CBC mode, and also includes
            12 bytes of known plaintext by design. This implies that a
            sufficiently knowledgeable attacker can inject arbitrary content
            into your encrypted files without knowledge of the password.

            Adding a digital signature to the encrypted document is **not**
            a foolproof way to deal with this either, since most viewers will
            still allow the document to be opened before signatures are
            validated, and therefore end users are still exposed to potentially
            malicious content.

            Until the standard supports authenticated encryption schemes, you
            should **never** rely on its encryption provisions if tampering
            is a concern.


        :param owner_pass:
            The desired owner password.
        :param user_pass:
            The desired user password (defaults to the owner password
            if not specified)
        :param kwargs:
            Other keyword arguments to be passed to
            :meth:`.StandardSecurityHandler.build_from_pw`.
        N)r   build_from_pwr   )r^   
owner_pass	user_passkwargsr   s        r=   encryptzPdfFileWriter.encryptE  s2    L %22	
%+
 	%%b)r>   
recipientsc                 `    d| _         t        j                  |fi |}| j                  |       y)a=  
        Mark this document to be encrypted with PDF 2.0 public key encryption.
        The certificates passed in should be RSA certificates.

        PyHanko defaults to AES-256 to encrypt the actual file contents.
        The seed used to derive the file encryption key is also encrypted
        using AES-256 and bundled in a CMS EnvelopedData object.
        The envelope key is then encrypted separately for each recipient, using
        their respective public keys.

        .. caution::
            The caveats for :meth:`encrypt` also apply here.

        :param recipients:
            Certificates of the recipients that should be able to decrypt
            the document.
        :param kwargs:
            Other keyword arguments to be passed to
            :meth:`.PubKeySecurityHandler.build_from_certs`.
        r   N)rq   r   build_from_certsr   )r^   r  r  r   s       r=   encrypt_pubkeyzPdfFileWriter.encrypt_pubkeyp  s/    * %"33JI&I%%b)r>   rw   rx   c                 "    || j                   |<   y)rz   N)r  r}   s      r=   r~   z&PdfFileWriter.set_custom_trailer_entry  s    " -2$$S)r>   c                 Z    |j                  | j                         t        |   |       y rh   )updater  r  r  )r^   r  r  s     r=   r  zPdfFileWriter._populate_trailer  s"    t334!'*r>   )TTNrh   )r   ry  rz  r{  r`   r   r  r   r   Certificater  r   ro  r  r~   r  r  r  s   @r=   r&   r&   !  sX    '>45)*V*d.>.>)? *22%%2.5.?.?2&+ +r>   r&   c            	           e Zd Zdededeej                  ej                  f   de	e
   fdZdej                  dej                  fdZdej                  fd	Zd
ej                  dej                  fdZd Zy)rF  rC  rD  rE  r   c                 J    || _         || _        || _        g | _        || _        y rh   )rC  rD  r   queued_referencesrE  )r^   rC  rD  rE  r   s        r=   r`   z_ObjectImporter.__init__  s0     $  	 +r>   r   r+   c                 d   | j                  |      }| j                  r| j                  j                         \  }}|j                         }| j                  |      }t	        |t
              rd }n| j                  }| j                  j                  |||j                         | j                  r|S )N)r   rW   )
_ingestr  poprl   rO   r   r   rD  rR   rW   )r^   r   r^  
source_ref
target_ref
source_objimportedr   s           r=   rI  z_ObjectImporter.import_object  s    c"$$%)%;%;%?%?%A"J
#..0J||J/H ($78!
!__
 KK""Zz7G7G #  $$" r>   c                     t        |t        j                        r|j                  }t        |t        j                        r j                  |j                        S t        |t        j                        r|j                         D ci c]  \  }}|dk7  s| j                  |       }}}	 |j                  d      }|j                         j                  |d        j                  |      |d<   t        |t        j                        rMt        j                  }	 ddlm} t        ||j$                        r|j$                  } |||j(                        S t        j                  |      S t        |t        j*                        rt        j*                   fd|D              S |S c c}}w # t        t        f$ r Y w xY w# t&        $ r Y w xY w)Nr   T)r   r   r   rT  c              3   @   K   | ]  }j                  |        y wrh   )r  )rQ  vr^   s     r=   rS  z*_ObjectImporter._ingest.<locals>.<genexpr>  s     &D1t||A&Ds   )rO   r   DecryptedObjectProxy	decryptedrP   process_referencer   r5   rr  r  get_value_as_referencerH  rl   rd   r   r6   r   r   r   r   rU  r7   )r^   r   kr  raw_dictmeta_refstm_clsr   s   `       r=   r  z_ObjectImporter._ingest  s   c7778--Cc7112))#--88W556/2yy{'+q!a;>N4<<?"H 
55kB((*55 6  )-(>(>x(H% #w334!..B!#w'='=>")"8"8 xc6F6FGG//99W001&&&D&DDDJI 45  # s1   
F,F,0AF2 !(G 2GG	GGr   c                     	 | j                   |   S # t        $ rU | j                  j                         }|| j                   |<   | j                  j                  ||j                  f       |cY S w xY wrh   )rE  rd   rD  r   r  r   r   )r^   r   new_idos      r=   r  z!_ObjectImporter.process_reference  sm    	%%c** 	kk668G&-Ds#""))30A0A*BCN	s    AA/.A/c           	         ddl m}  || j                  d      D cg c],  \  }}}t        |t        j
                        r|j                  . }}}}|rt        j                  d       |D ]  }|j                         }t        |t        j                        sJ |j                         D 	ci c]  \  }}	|dk7  r|| j                  |	       }
}}	t	        j                  |j                  dt        j                  j                         j"                        |
d<   | j$                  j'                  t	        j                  |
      d       | j(                  |<    y c c}}}w c c}	}w )	Nr   )enumerate_sig_fieldsT)filled_statuszZSource document contains filled signature fields--the copy operation will invalidate them.rN  r   )r   )sign.fieldsr  rC  rO   r   rP   r   loggerwarningrl   r5   rr  r  r  r   r   r   r   rD  rR   rE  )r^   r  fq_namefield_value	field_refsignature_dict_refsr   sig_dictr  r  r  s              r=   preprocess_signature_dataz)_ObjectImporter.preprocess_signature_data  sb   
 	7 4H44
 
/i +w'='=> !!
 
 NN2 ' 	C~~'Hh(@(@AAA %NN,Aq# 4<<?"H 
 %,$<$<  )C)C)G)G !  .%H[!
 '+kk&<&<((2 '= 'Ds#	
 s   1E/!E%N)r   ry  rz  r   r$   r   r   r   rP   r   r   r`   r  rI  r  r  r  r   r>   r=   rF  rF    s    ++ "+ G--w/E/EEF	+
 \*+!2!2 w7H7H ,*7,, *XW%6%6 7;L;L $r>   rF  input_handlerwriter_kwargsc           
      T   |xs i }|j                  dd       t        d	ddi|}| j                  }|j                  }t        | ||t	        j
                  |j                  |j                  |      id      }|j                          |j                  | j                        }|j                  |j                  f}||j                  |<   d|vrH	 | j                  d   }|6t        | |i d      }|j                  |      }	|j                  |	      |_        |S # t        $ r d}Y Gw xY w)
a  
    Copy all objects in a given PDF handler into a new :class:`.PdfFileWriter`.
    This operation will attempt to preserve the document catalog
    of the original ``input_handler``.

    Very roughly, calling this function and then immediately invoking
    :meth:`~.BasePdfFileWriter.write` on the resulting writer should result
    in an equivalent document as far as presentation is concerned.
    As a general rule, behaviour that is controlled from outside the document
    catalog (e.g. encryption) or that requires byte-for-byte equivalence with
    the original (e.g. digital signatures) will not survive this translation.


    :param input_handler:
        :class:`.PdfHandler` to source objects from.
    :param writer_kwargs:
        Keyword arguments to pass to the writer.
    :return:
        New :class:`.PdfFileWriter` containing all objects from the input
        handler.
    rA   Fr  )rW   rX   r   N)rC  rD  rE  r   rC   r  r   )
setdefaultr&   r   rF  r   rP   rW   rX   r  rI  rB   rH   r  rd   rR   rY   )
r  r  winput_root_refoutput_root_refrJ  new_root_dictr   r   imported_infos
             r=   r(   r(   &  sH   2 "'RM^U3 	<U<m<A"++NjjO G22%++*55
 H &&(**=+=+=>M

$
$o&;&;	<B!AIIbM]"	
 &227;I  &$ 	H %229=Mll=1AGH  	I	s   D D'&D'rh   )=r{  loggingr  typingr   r   r   r   r   r   r	   r
   
asn1cryptor   pyhanko.pdf_utilsr   r  r   r   r   pyhanko.pdf_utils.extensionsr   r   pyhanko.pdf_utils.genericr   pyhanko.pdf_utils.metadata.infor   r    pyhanko.pdf_utils.metadata.modelr   pyhanko.pdf_utils.miscr   r   r   r   r   pyhanko.pdf_utils.rw_commonr   pyhanko.pdf_utils.xrefr   r   r   r   r    TYPE_CHECKINGrc   r#   __all__	getLoggerr   r  r  r5   r6   r'   r$   r%   r&   rF  dictr(   r   r>   r=   <module>r     s'    	  J J J  % 
 / >  3  
. 
		8	$ 59	$$ 001	$
 $NV
 Vr!
)) !
H~+% ~+BA AJ @DJJ.6tnJJr>   