ó
    �®žjO'  ã                   óú   • S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKJr  SSKJrJr  SSKrSSKJr  SSKJrJr  SS	KJr  SS
KJr  \R6                  " \5      rS\SS4S jr " S S5      r g)a]  Shared image-resource loading for declarative backends.

Turns an image source (a URI, a local file, or a remote URL) into a DoclingDocument
`ImageRef`, enforcing the relevant safety limits: a path-traversal guard when resolving
relative paths, the `enable_local_fetch` / `enable_remote_fetch` toggles, and the
base64 and remote download size caps.
é    N)ÚBytesIO)ÚPath)ÚOptional)ÚurljoinÚurlparse)ÚImageRef)ÚImageÚUnidentifiedImageError)ÚValidationError)ÚOperationNotAllowedÚurlÚreturnc                 ó~  • [        U 5      nUR                  nU(       d  [        S5      e [        R                  " U5      nUR                  (       af  UR                  (       dU  UR                  (       dD  UR                  (       d3  UR                  (       d"  UR                  (       d  UR                  (       a  [        SU 35      eg! [         ak     [
        R                  " U5      n[        R                  " U5      n N¿! [
        R                  [
        R                  4 a  n[        SU 35      UeSnAff = ff = f)a³  Reject URLs that resolve to a non-public IP address.

Guards against SSRF by requiring the URL's host to resolve to a globally
routable address. Private, loopback, link-local, reserved, multicast, and
unspecified addresses are refused.

Args:
    url: The URL whose host is validated.

Raises:
    ValueError: If the URL has no hostname, the hostname cannot be
        resolved, or it resolves to a restricted (non-global) IP address.
z!URL must contain a valid hostnamezCannot resolve hostname: Nz-Access to restricted IP address not allowed: )r   ÚhostnameÚ
ValueErrorÚ	ipaddressÚ
ip_addressÚsocketÚgethostbynameÚgaierrorÚherrorÚ	is_globalÚ
is_privateÚis_loopbackÚis_link_localÚis_reservedÚis_multicastÚis_unspecified)r   Úparsedr   ÚipÚip_strÚes         Úh/home/mande/repo/quber/.venv/lib/python3.13/site-packages/docling/backend/utils/image_resource_loader.pyÚvalidate_url_safetyr$   "   sù   € ô �c‹]€FØ�‰€HæÜÐ<Ó=Ð=ðLÜ×!Ò! (Ó+ˆð 	��à�M�MØ�~�~Ø××Ø�~�~Ø��Ø× × ô ÐHÈÈÐMÓNÐNð !øô ó Lð	LÜ×)Ò)¨(Ó3ˆFÜ×%Ò% fÓ-ŠBøÜ—‘¤§¡Ð/ó 	LÜÐ8¸¸
ÐCÓDÈ!ÐKûð	Lúð	Lús)   «C Ã
D<Ã,D Ä $D8Ä$D3Ä3D8Ä8D<c                   ó6  • \ rS rSrSrSSSSSSS.S\S	\S
\S\S\S\\\	\	4      SS4S jjr
\S\	S\4S j5       r\S\	S\4S j5       r\S\	S\4S j5       rS\	S\\	   S\	4S jrS\	S\\	   S\\   4S jrS\	S\\	   S\\   4S jrS\	S\\	   S\\   4S jrSrg)ÚImageResourceLoaderéM   a  Resolve and load image resources for declarative document backends.

The `base_path` against which relative locations are resolved is supplied
per call rather than stored, so a backend that mutates its base path between
calls always uses the current value.
Fi  @é   N©Úenable_local_fetchÚenable_remote_fetchÚmax_image_data_base64_bytesÚmax_remote_image_bytesÚmax_redirectsÚheadersr*   r+   r,   r-   r.   r/   r   c                óL   • Xl         X l        X0l        X@l        XPl        X`l        g )Nr)   )Úselfr*   r+   r,   r-   r.   r/   s          r#   Ú__init__ÚImageResourceLoader.__init__U   s'   € ð #5ÔØ#6Ô Ø+FÔ(Ø&<Ô#Ø*ÔØ�ó    Úvaluec                 ó6   • [        U 5      nUR                  S;   $ )N>   ÚgsÚs3ÚftpÚhttpÚhttps)r   Úscheme©r5   r   s     r#   Úis_remote_urlÚ!ImageResourceLoader.is_remote_urlf   s   € ä˜%“ˆØ�}‰}Ð DÑDÐDr4   c                 óê   • [        U 5      nUR                  (       + =(       aQ    UR                  (       + =(       d9    [        UR                  5      S:H  =(       a    UR                  R	                  5       $ )z6Check if value is a local filesystem path (not a URI).é   )r   Únetlocr<   ÚlenÚisalphar=   s     r#   Úis_local_pathÚ!ImageResourceLoader.is_local_pathk   sT   € ô ˜%“ˆØ—=‘=Ô ÷ 
Ø—‘Ô÷ EÜ�F—M‘MÓ" aÑ'×C¨F¯M©M×,AÑ,AÓ,Cð	
r4   Úlocc                 óú   • [        U 5      R                  5       =(       d\    [        [        U 5      =nR                  5      S:H  =(       a2    UR                  R                  5       =(       a    UR                  (       + $ )NrA   )r   Úis_absoluterC   r   r<   rD   rB   )rG   Ú
parsed_locs     r#   Úis_absolute_pathÚ$ImageResourceLoader.is_absolute_patht   s`   € ä�C‹y×$Ñ$Ó&÷ 
Üœx¨›}Ð,�×4Ñ4Ó5¸Ñ:÷ &Ø×!Ñ!×)Ñ)Ó+÷&à×%Ñ%Ô%ð	
r4   Ú	base_pathc                 óÜ  • UR                  5       nUR                  S=n5      (       a  U[        U5      S  nUnU(       Ga  UR                  S5      (       a  SU-   nOôUR                  S5      (       dÞ  [        R	                  U5      (       a  [        X!5      nO¸[        R                  U5      (       a�  [        R                  U5      (       a  [        SU S35      e[        U5      R                  R                  5       nXQ-  R                  5       nUR                  U5      (       d  [        SU S35      e[        U5      nO[        S	U S35      e[        R                  S
U SU 35        U$ )Nzfile://z//zhttps:)úhttp://úhttps://údata:Ú#z6Absolute paths are not allowed with local base_path: 'Ú'zPath traversal blocked: 'z!' resolves outside base directoryzInvalid base_path format: 'zResolved location z to )ÚstripÚ
startswithrC   r&   r>   r   rE   rK   r   r   ÚparentÚresolveÚis_relative_toÚstrÚ_logÚdebug)r1   rG   rM   Úfile_prefixÚabs_locÚbase_dirÚresolved_paths          r#   Úresolve_relative_pathÚ)ImageResourceLoader.resolve_relative_path|   sS  € Ø�i‰i‹kˆð �>‰>¨Ð2˜+×3Ñ3Ø”c˜+Ó&Ð(Ð)ˆCàˆçØ�~‰~˜d×#Ñ#Ø" S™.‘Ø—^‘^Ð$I×JÑJÜ&×4Ñ4°Y×?Ñ?Ü% iÓ5‘GÜ(×6Ñ6°y×AÑAÜ*×;Ñ;¸C×@Ñ@Ü(ØTÐUXÐTYÐYZÐ[óð ô  $ I›×5Ñ5×=Ñ=Ó?�HØ%-¡^×$<Ñ$<Ó$>�Mà(×7Ñ7¸×AÑAÜ(Ø7¸°uÐ<]Ð^óð ô " -Ó0‘Gä$Ð'BÀ9À+ÈQÐ%OÓPÐPä�
‰
Ð'¨ u¨D°°	Ð:Ô;Øˆr4   Úsrc_urlc           	      óš  •  U R                  X5      nU(       aZ  [        R                  " [        U5      5      n[        R
                  " U[        UR                  R                  SS5      S   5      S9$  g ! [        R                  [        [        [        [        [        4 a&  n[         R"                  " SU SU 35         S nAg S nAff = f)NÚdpi)éH   r   )rd   z Could not process an image from z: )Úload_image_datar	   Úopenr   r   Úfrom_pilÚintÚinfoÚgetÚrequestsÚ	HTTPErrorr   r
   r   Ú	TypeErrorr   ÚwarningsÚwarn)r1   rb   rM   Úimg_dataÚimgr"   s         r#   Úcreate_image_refÚ$ImageResourceLoader.create_image_refŸ   sµ   € ð	MØ×+Ñ+¨GÓ?ˆHÞÜ—j’j¤¨Ó!2Ó3�Ü×(Ò(¨´#°c·h±h·l±lÀ5È%Ó6PÐQRÑ6SÓ2TÑUÐUð ð øô ×ÑÜÜ"ÜÜÜð
ó 	Mô �MŠMÐ<¸W¸IÀRÈÀsÐK×LÐLàûð	Mús   ‚A1A6 Á6.C
Â$CÃC
Úsrcc                 óD   • U R                  U R                  X5      U5      $ )zAResolve `src` against `base_path` and decode it into an ImageRef.)rs   r`   )r1   ru   rM   s      r#   Úload_image_refÚ"ImageResourceLoader.load_image_ref³   s%   € à×$Ñ$Ø×&Ñ& sÓ6¸	ó
ð 	
r4   Úsrc_locc                 ó  • UR                  5       R                  S5      (       a  [        R                  SU 35        g [        R                  U5      (       Gau  U R                  (       d  [        S5      e[        U5        U R                  nSSUS-
   30nU R                  (       a  UR                  U R                  5        [        R                  " 5       nU R                  Ul        S nUR                  S   R!                  U5        UR#                  US	US
S9nUR%                  5         UR                  R#                  S5      nU(       a  ['        U5      U:”  a  [)        SU S35      e/ n	Sn
UR+                  SS9 H;  nU(       d  M  U
[-        U5      -  n
X£:”  a  [)        S5      eU	R!                  U5        M=     SR/                  U	5      $ UR1                  S5      (       ab  [2        R4                  " SSU5      n[6        R8                  " U5      n[-        U5      U R:                  :”  a  [)        SU R:                   S35      eU$ U R<                  (       d  [        S5      eU(       d  [        SU S35      e[>        R@                  RC                  U5      (       aP  [>        RD                  " U[>        RF                  5      (       a&  [I        US5       nURK                  5       sS S S 5        $ [)        S5      e! , (       d  f       g = f)Nz.svgzSkipping SVG file: zdFetching remote resources is only allowed when set explicitly. Set options.enable_remote_fetch=True.ÚRangezbytes=0-rA   c                 óþ   • U R                   (       d  U R                  (       a[  U R                  R                  S5      nU(       a8  UR	                  S5      (       d  [        U R                  U5      n[        U5        ggg)z2Validate each redirect target before following it.Úlocation)rO   rP   N)Úis_redirectÚis_permanent_redirectr/   rk   rU   r   r   r$   )ÚresponseÚargsÚkwargsÚredirect_urls       r#   Ú_check_redirect_safetyÚCImageResourceLoader.load_image_data.<locals>._check_redirect_safetyÕ   sc   € à×'×'¨8×+I×+IØ#+×#3Ñ#3×#7Ñ#7¸
Ó#C�LÞ#à+×6Ñ6Ð7N×OÑOÜ+2°8·<±<ÀÓ+N˜Lô ,¨LÕ9ð $ð ,Jr4   r€   T)r(   é   )Ústreamr/   Útimeoutzcontent-lengthzResource size exceeds limit: z bytesr   i    )Ú
chunk_sizez"Downloaded data exceeds size limitr4   rQ   z^data:image/.+;base64,Ú z$Decoded image exceeds size limit of z bytes.zbFetching local resources is only allowed when set explicitly. Set options.enable_local_fetch=True.zALocal file access requires base_path for directory confinement: 'rS   Úrbz*File does not exist or it is not readable.)&ÚlowerÚendswithrZ   r[   r&   r>   r+   r   r$   r-   r/   Úupdaterl   ÚSessionr.   ÚhooksÚappendrk   Úraise_for_statusri   r   Úiter_contentrC   ÚjoinrU   ÚreÚsubÚbase64Ú	b64decoder,   r*   ÚosÚpathÚisfileÚaccessÚR_OKrg   Úread)r1   ry   rM   Úmax_sizer/   Úsessionr„   r€   Úcontent_lengthÚchunksÚ
total_sizeÚchunkÚencoded_dataÚdecoded_dataÚfs                  r#   rf   Ú#ImageResourceLoader.load_image_data¹   s³  € ð �=‰=‹?×#Ñ# F×+Ñ+Ü�J‰JÐ,¨W¨IÐ6Ô7Øä×,Ñ,¨W×5Ò5Ø×+×+Ü)ð<óð ô
   Ô(à×2Ñ2ˆHØ (¨8°a©<¨.Ð 9Ð:ˆGð �|�|Ø—‘˜tŸ|™|Ô,ô ×&Ò&Ó(ˆGØ$(×$6Ñ$6ˆGÔ!ò
:ð �M‰M˜*Ñ%×,Ñ,Ð-CÔDà—{‘{Ø ¨g¸wð #ð ˆHð ×%Ñ%Ô'à%×-Ñ-×1Ñ1Ð2BÓCˆNÞ¤# nÓ"5¸Ó"@Ü Ð#@ÀÐ@PÐPVÐ!WÓXÐXàˆFØˆJØ!×.Ñ.¸$Ð.Ó?�ß�5Ø¤# e£*Ñ,�JØ!Ó,Ü(Ð)MÓNÐNØ—M‘M %Ö(ñ @ð —8‘8˜FÓ#Ð#Ø×Ñ ×(Ñ(ÜŸ6š6Ð";¸RÀÓIˆLÜ!×+Ò+¨LÓ9ˆLä�<Ó  4×#CÑ#CÓCÜ Ø:¸4×;[Ñ;[Ð:\Ð\cÐdóð ð  Ðà×&×&Ü%ð7óð ö Ü%ØSÐT[ÐS\Ð\]Ð^óð ô �7‰7�>‰>˜'×"Ñ"¤r§y¢y°¼"¿'¹'×'BÑ'BÜ�g˜tÔ$¨Ø—v‘v“x÷ %Ñ$ô ÐIÓJÐJ÷ %Õ$ús   ËK7Ë7
L)r*   r+   r/   r,   r.   r-   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Úboolri   r   ÚdictrY   r2   Ústaticmethodr>   rE   rK   r`   r   rs   rw   Úbytesrf   Ú__static_attributes__© r4   r#   r&   r&   M   sr  † ñð $)Ø$)Ø+;Ø&6ØØ,0òð !ðð "ð	ð
 &)ðð !$ðð ðð ˜$˜s C˜x™.Ñ)ðð 
õð" ðE˜Sð E Tó Eó ðEð ð
˜Sð 
 Tó 
ó ð
ð ð
˜cð 
 dó 
ó ð
ð!¨ð !¸À#¹ð !È3ô !ðFØðØ'/°¡}ðà	�(Ñ	ôð(
 #ð 
°(¸3±-ð 
ÀHÈXÑDVô 
ðXKØðXKØ'/°¡}ðXKà	�%‰÷XKr4   r&   )!r­   r—   r   Úloggingr™   r•   r   ro   Úior   Úpathlibr   Útypingr   Úurllib.parser   r   rl   Údocling_core.types.doc.documentr   ÚPILr	   r
   Úpydanticr   Údocling.exceptionsr   Ú	getLoggerr©   rZ   rY   r$   r&   r³   r4   r#   Ú<module>r¾      sq   ðñó Û Û Û 	Û 	Û Û Ý Ý Ý ß *ã Ý 4ß -Ý $å 2à×Ò˜Ó"€ð(O˜Sð (O Tô (O÷VDKò DKr4   