
    hl                     h   S 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J	r	J
r
Jr  SSKJrJrJr  SSKJr  SSKJr  SSKJr  SS	KJr  S
r " S S\5      r " S S\5      rSrSrSr\" \\/5      r Sr! " S S5      r" " S S5      r# " S S5      r$ " S S5      r% " S S5      r&S r'S r( " S S 5      r)g)!z
Multi-part parsing for file uploads.

Exposes one class, ``MultiPartParser``, which feeds chunks of uploaded data to
file upload handlers for processing.
    N)settings)RequestDataTooBigSuspiciousMultipartFormTooManyFieldsSentTooManyFilesSent)SkipFileStopFutureHandlers
StopUpload)MultiValueDict)	force_str)parse_header_parameters)_lazy_re_compile)MultiPartParserMultiPartParserErrorInputStreamExhaustedc                       \ rS rSrSrg)r       N)__name__
__module____qualname____firstlineno____static_attributes__r       M/var/www/html/env/lib/python3.13/site-packages/django/http/multipartparser.pyr   r      s    r   r   c                       \ rS rSrSrSrg)r   !   z-
No more reads are allowed from this device.
r   N)r   r   r   r   __doc__r   r   r   r   r   r   !   s     	r   r   rawfilefield   c                   T    \ rS rSrSr\" S5      rSS jrS rS r	S r
S	 r\rS
 rSrg)r   0   z
An RFC 7578 multipart/form-data parser.

``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
z[ -~]{0,200}[!-~]Nc                 L   UR                  SS5      nUR                  S5      (       d  [        SU-  5      e UR                  S5        [        U5      u  pgUR                  S5      nU(       a   U R                  R                  U5      (       d  [        S[        U5      -  5      e [        UR                  S	S
5      5      n	U	S
:  a  [        SU	-  5      eUR                  S5      U l        X l        U V
s/ s H!  oR                  (       d  M  U
R                  PM#     nn
[        S/U-   5      U l        Xl        U=(       d    [$        R&                  U l        Xl        X0l        g! [         a    [        S[        U5      -  5      ef = f! [        [        4 a    S
n	 Nf = fs  sn
f )aX  
Initialize the MultiPartParser object.

:META:
    The standard ``META`` dictionary in Django request objects.
:input_data:
    The raw post data, as a file-like object.
:upload_handlers:
    A list of UploadHandler instances that perform operations on the
    uploaded data.
:encoding:
    The encoding with which to treat the incoming data.
CONTENT_TYPE z
multipart/zInvalid Content-Type: %sasciiz/Invalid non-ASCII Content-Type in multipart: %sboundaryz!Invalid boundary in multipart: %sCONTENT_LENGTHr   zInvalid content length: %riN)get
startswithr   encodeUnicodeEncodeErrorr   r   boundary_re	fullmatchint
ValueError	TypeError	_boundary_input_data
chunk_sizemin_chunk_size_metar   DEFAULT_CHARSET	_encoding_content_length_upload_handlers)selfMETA
input_dataupload_handlersencodingcontent_type_optsr)   content_lengthxpossible_sizess               r   __init__MultiPartParser.__init__:   s    xx3&&|44&'AL'PQQ	( *,788J't//99(CC&3i6II 	 *:A!>?N A&'Cn'TUU!1% 1@P1<<,!,,P	{^;<
!=X%=%=- /I " 	&AL)* 	$ I& 	N	 Qs)   E$ &F	 5F!F!$"F	FFc                      U R                  5       $ ! [         aO    [        U S5      (       a<  U R                  R	                  5        H  u  pU H  nUR                  5         M     M      e f = f)N_files)_parse	ExceptionhasattrrL   listsclose)r>   rD   filesfileobjs       r   parseMultiPartParser.parseu   s`    	;;=  	tX&& $ 1 1 3HA#( $) !4 	s
    AA+c           
      p   SSK Jn  U R                  nU R                  nU R                  S:X  a  U" U R                  S9[        5       4$ U HO  nUR                  U R                  U R                  U R                  U R                  U5      nUc  ME  US   US   4s  $    U" SS9U l
        [        5       U l        [        [        U R                  U R                  5      5      nSnS/[        U5      -  nSn	Sn
SnSnSn [!        X`R                  5       GH  u  pnU(       a  U R#                  Xx5        SnSnU[$        ;   a8  [&        R(                  b'  U
S-  n
[&        R(                  S-   U
:  a  [+        S	5      e US
   S   nUS   R-                  5       nUR5                  S5      nUb  US   R-                  5       n[7        UUSS9nU[8        :X  a  [&        R:                  b  [&        R:                  U	-
  nUS:X  a5  UR=                  US9nU	[        U5      -  n	 [>        R@                  " U5      nOUR=                  US9nU	[        U5      -  n	U	[        U5      S-   -  n	[&        R:                  b  U	[&        R:                  :  a  [G        S5      eU R                  RI                  U[7        UUSS95        GM  U[J        :X  Ga  US-  n[&        RL                  b  U[&        RL                  :  a  [O        S5      eUR5                  S5      nU(       a  [7        UUSS9nU RQ                  U5      nU(       d  GM   UR5                  SS0 45      u  nnUR-                  5       nUR5                  S5      n [S        UR5                  S5      S   5      nS/[        U5      -  nSn U H  n URY                  UUUUUU5        M     U H  nUS:X  a  SR]                  UR_                  5       5      n[        U5      S-  nUS:w  aT  UR=                  SU-
  5      nU(       d  O8USR]                  UR_                  5       5      -  n[        U5      S-  nUS:w  a  MT   [>        R@                  " U5      n[e        U5       H9  u  n n[        U5      n!URg                  UUU    5      nUU ==   U!-  ss'   Ub  M8    M     M     UnGM  [m        U5        GM     U(       d  U H  nURo                  5         M     [m        U R                  5        [u        S U 5       5        SU R                  l;        U R                  U R                  4$ ! [.        [0        [2        4 a     GM;  f = f! [B        RD                   a    Un GNf = f! [0        [T        [V        4 a    Sn GN f = f! [Z         a       GM  f = f! [`         a  n[c        S5      UeSnAff = f! [h         a     U Rk                  5         [m        U5         GM  f = f! [p         aA  n"U Rk                  5         U"Rr                  (       d  [m        U R                  5         Sn"A"GN7Sn"A"ff = f)z
Parse the POST data and break it into a FILES MultiValueDict and a POST
MultiValueDict.

Return a tuple containing the POST and FILES dictionary, respectively.
r   )	QueryDict)rB   N   T)mutable   zRThe number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.content-dispositionnamezcontent-transfer-encodingreplaceerrorsbase64)sizez;Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.zCThe number of files exceeded settings.DATA_UPLOAD_MAX_NUMBER_FILES.filenamezcontent-typer'   charsetzcontent-lengthFr      zCould not decode base64 data.c              3   @   #    U  H  oR                  5       v   M     g 7fN)upload_complete).0handlers     r   	<genexpr>)MultiPartParser._parse.<locals>.<genexpr>k  s     >X'##%%Xs   )<django.httprW   r;   r=   r<   r   handle_raw_inputr5   r9   r4   _postrL   
LazyStream	ChunkIterr8   lenParserhandle_file_completeFIELD_TYPESr   DATA_UPLOAD_MAX_NUMBER_FIELDSr   stripKeyError
IndexErrorAttributeErrorr+   r   FIELDDATA_UPLOAD_MAX_MEMORY_SIZEreadr`   	b64decodebinasciiErrorr   
appendlistFILEDATA_UPLOAD_MAX_NUMBER_FILESr   sanitize_file_namer1   r3   r2   new_filer	   joinsplitrN   r   	enumeratereceive_data_chunkr   _close_filesexhaustupload_interruptedr
   connection_resetany_mutable)#r>   rW   rB   handlersri   resultstreamold_field_namecountersnum_bytes_readnum_post_keys	num_files	read_sizeuploaded_file	item_type	meta_datafield_streamdisposition
field_nametransfer_encodingraw_datadata	file_namerC   content_type_extrarc   rF   chunkstripped_chunk	remaining
over_chunkexcichunk_lengthes#                                      r   rM   MultiPartParser._parse   s>    	*>>(( 1$dnn5~7GGG  G--  

$$F !ay&)++   t,
$& Id&6&68H8HIJ 3X& 		m	&6<V^^6T2	l! --nG%)N$(M , >>J "Q&M  ==AMQ/F 
"+,A"B1"EK!,V!4!:!:!<J %.MM2M$N!$0(9!(<(B(B(D%&z8IN
%;;G$@@>Q "
 )H4#/#4#4)#4#D&#h-7,#)#3#3H#=D  ,00i0@&#d)3 #c*o&99N <<H*X-Q-QQ/D 
 JJ))"IdHY$O $&NI ==I%(M(MM.E 
 !,
 ;I $-i)$T	$($;$;I$F	$ 7@}}&R84L"4 $0#5#5#7L044Y?G.),Y]];K-LQ-O)P !"sS]2H$)M64'/G
& ' 0 0$.$-$0$2$+$6!" (0 &2E0H<
 25%++-1H,/,?!,C	&/1n1=1B1B1y=1QJ+5(-$2chhz?O?O?Q6R$RN03N0Ca0GI '01n!/,2,<,<^,LE /8.A
7/25z(/(B(B5(ST+(V (| ;#(= %* /B3 &2P *4 L)E 7UP !'G..0  ( D$$% 	>X>>#

zz4;;&&q !*n= *  (~~ ,#+D,` '	:> .)-.  $6 & %&* (1 !/ +?(G+&+.%/!/  $ .))+--.  	*%%(()	*s   =A:W* 8T4BW* U-D=W* +U.W* V= V6BV=V#?V=&	V=/W* 4U	W* UW* U+'W* *U++W* .V	W* V		W* 
VV=VV=
V:)V55V::V==%W'"W* &W''W* *
X546X00X5c           	          [        U R                  5       HO  u  p4UR                  X#   5      nU(       d  M!  U R                  R	                  [        XR                  SS9U5          g   g)zD
Handle all the signaling that takes place when a file is complete.
r]   r^   N)r   r=   file_completerL   r   r   r;   )r>   r   r   r   ri   file_objs         r   rs   $MultiPartParser.handle_file_completeo  sZ     $D$9$9:JA,,X[9Hx&&nnnYO  ;r   c                 
   [         R                  " U5      nUR                  S5      S   nUR                  S5      S   nSR                  U Vs/ s H  o"R	                  5       (       d  M  UPM     sn5      nUS;   a  gU$ s  snf )a  
Sanitize the filename of an upload.

Remove all possible path separators, even though that might remove more
than actually required by the target system. Filenames that could
potentially cause problems (current/parent dir) are also discarded.

It should be noted that this function could still return a "filepath"
like "C:some_file.txt" which is handled later on by the storage layer.
So while this function does sanitize filenames to some extent, the
resulting filename should still be considered as untrusted user input.
/\r'   >   r'   ...N)htmlunescapersplitr   isprintable)r>   r   chars      r   r   "MultiPartParser.sanitize_file_name}  sy     MM),	$$S)"-	$$T*2.	GGiNid;K;K;MTiNO	'	 Os   B *B c                     U R                    H0  n[        US5      (       d  M  UR                  R                  5         M2     g )Nr    )r=   rO   r    rQ   )r>   ri   s     r   r   MultiPartParser._close_files  s1    
 ,,Gw''""$ -r   )	r4   r8   r<   r;   rL   r5   r9   rn   r=   rf   )r   r   r   r   r   r   r/   rI   rT   rM   rs   r   IE_sanitizer   r   r   r   r   r   r   0   s<     ##78K90v h'T. %K%r   r   c                   P    \ rS rSrSrSS jrS rSS jrS rS r	S	 r
S
 rS rSrg)ro   i  a  
The LazyStream wrapper allows one to get and "unget" bytes from a stream.

Given a producer object (an iterator that yields bytestrings), the
LazyStream object will support iteration, reading, and keeping a "look-back"
variable in case you need to "unget" some bytes.
Nc                 `    Xl         SU l        SU l        X l        SU l        X l        / U l        g)z
Every LazyStream must have a producer when instantiated.

A producer is an iterable that returns a string each time it
is called.
Fr   r   N)	_producer_empty	_leftoverlengthposition
_remaining_unget_history)r>   producerr   s      r   rI   LazyStream.__init__  s0     "  r   c                     U R                   $ rf   )r   r>   s    r   tellLazyStream.tell  s    }}r   c                 @   ^ ^ U U4S jnSR                  U" 5       5      $ )Nc               3   "  >#    Tc  TR                   OTn U c  SR                  T5      v   g U S:w  aL  U S:  d   S5       e [        T5      nUS U  nTR                  XS  5        U [	        U5      -  n Uv   U S:w  a  MK  g g ! [
         a     g f = f7f)Nr   r   z0remaining bytes to read should never go negative)r   r   nextungetrq   StopIteration)r   r   emittingr>   ra   s      r   partsLazyStream.read.<locals>.parts  s     +/<TI hhtn$
 q. 1}X&XX}# JE  %Zi0HJJuZ01X.I"N q.
 % s/   <B A? 0B=B?
B	BBBr   )r   )r>   ra   r   s   `` r   r|   LazyStream.read  s    	#. xx  r   c                     U R                   (       a  U R                   nSU l         O[        U R                  5      n/ U l        U =R                  [        U5      -  sl        U$ )z
Used when the exact number of bytes to read is unimportant.

Return whatever chunk is conveniently returned from the iterator.
Useful to avoid unnecessary bookkeeping if performance is an issue.
r   )r   r   r   r   r   rq   )r>   outputs     r   __next__LazyStream.__next__  sH     >>^^F DN$..)F"$DV$r   c                     / U l         g)z
Used to invalidate/disable this lazy stream.

Replace the producer with an empty list. Any leftover bytes that have
already been read will still be reported upon read() and/or next().
N)r   r   s    r   rQ   LazyStream.close  s     r   c                     U $ rf   r   r   s    r   __iter__LazyStream.__iter__      r   c                     U(       d  gU R                  [        U5      5        U =R                  [        U5      -  sl        XR                  -   U l        g)z
Place bytes back onto the front of the lazy stream.

Future calls to read() will return those bytes first. The
stream position and thus tell() will be rewound.
N)_update_unget_historyrq   r   r   )r>   bytess     r   r   LazyStream.unget  s<     ""3u:.U#/r   c                     U/U R                   SS -   U l         [        U R                    Vs/ s H  nX!:X  d  M
  UPM     sn5      nUS:  a  [        S5      egs  snf )a*  
Update the unget history as a sanity check to see if we've pushed
back the same number of bytes in one chunk. If we keep ungetting the
same number of bytes many times (here, 50), we're mostly likely in an
infinite loop of some sort. This is usually caused by a
maliciously-malformed MIME request.
N1   (   zThe multipart parser got stuck, which shouldn't happen with normal uploaded files. Check for malicious upload activity; if there is none, report this to the Django developers.)r   rq   r   )r>   	num_bytescurrent_numbernumber_equals       r   r    LazyStream._update_unget_history  sz      )kD,?,?,DD '+&9&9&9N!. &9
 ")K  s
   	AA)r   r   r   r   r   r   r   rf   )r   r   r   r   r   rI   r   r|   r   rQ   r   r   r   r   r   r   r   ro   ro     s/    !!4 0r   ro   c                   .    \ rS rSrSrSS jrS rS rSrg)	rp   i  z
An iterable that will yield chunks of data. Given a file-like object as the
constructor, yield chunks of read operations from that object.
c                     Xl         X l        g rf   )flor6   )r>   r   r6   s      r   rI   ChunkIter.__init__  s    $r   c                      U R                   R                  U R                  5      nU(       a  U$ [	        5       e! [         a    [	        5       ef = frf   )r   r|   r6   r   r   )r>   r   s     r   r   ChunkIter.__next__!  sH    	"88==1D K/! $ 	"/!	"s	   %: Ac                     U $ rf   r   r   s    r   r   ChunkIter.__iter__+  r   r   )r6   r   N)i   )	r   r   r   r   r   rI   r   r   r   r   r   r   rp   rp     s    
%"r   rp   c                   *    \ rS rSrSrS rS rS rSrg)InterBoundaryIteri/  z/
A Producer that will iterate over boundaries.
c                     Xl         X l        g rf   )_streamr4   r>   r   r)   s      r   rI   InterBoundaryIter.__init__4  s    !r   c                     U $ rf   r   r   s    r   r   InterBoundaryIter.__iter__8  r   r   c                      [        [        U R                  U R                  5      5      $ ! [         a    [        5       ef = frf   )ro   BoundaryIterr   r4   r   r   r   s    r   r   InterBoundaryIter.__next__;  s8    	"l4<<HII# 	"/!	"s	   (+ A )r4   r   N)	r   r   r   r   r   rI   r   r   r   r   r   r   r   r   /  s    ""r   r   c                   0    \ rS rSrSrS rS rS rS rSr	g)	r   iB  aI  
A Producer that is sensitive to boundaries.

Will happily yield bytes until a boundary is found. Will yield the bytes
before the boundary, throw away the boundary bytes themselves, and push the
post-boundary bytes back on the stream.

The future calls to next() after locating the boundary will raise a
StopIteration exception.
c                     Xl         X l        SU l        [        U5      S-   U l        U R                   R                  S5      nU(       d
  [        5       eU R                   R                  U5        g )NF   rX   )r   r4   _donerq   	_rollbackr|   r   r   )r>   r   r)   unused_chars       r   rI   BoundaryIter.__init__N  sY    !
 X* ll''*&((;'r   c                     U $ rf   r   r   s    r   r   BoundaryIter.__iter__]  r   r   c                    U R                   (       a
  [        5       eU R                  nU R                  nSn/ nU H2  nU[	        U5      -  nUR                  U5        X2:  a    OU(       a  M2    O	   SU l         U(       d
  [        5       eSR                  U5      nU R                  U5      nU(       a#  Uu  pUR                  XiS  5        SU l         US U $ US U*  (       d	  SU l         U$ UR                  Xb* S  5        US U*  $ )Nr   Tr   )	r  r   r   r  rq   appendr   _find_boundaryr   )
r>   r   rollback
bytes_readchunksr   r   r)   endr   s
             r   r   BoundaryIter.__next__`  s    ::/!>>
E#e*$JMM% $5  DJ/! &&u- ICLLu&DJ#; 8)$!
U9:./Zxi((r   c                     UR                  U R                  5      nUS:  a  gUnU[        U R                  5      -   n[        SUS-
  5      nXUS-    S:X  a  US-  n[        SUS-
  5      nXUS-    S:X  a  US-  nX44$ )z
Find a multipart boundary in data.

Should no boundary exist in the data, return None. Otherwise, return
a tuple containing the indices of the following:
 * the end of current encapsulation
 * the start of the next encapsulation
r   NrX      
   )findr4   rq   max)r>   r   indexr  r   lasts         r   r
  BoundaryIter._find_boundary  s     		$..)19C3t~~..Dq#'?D4!8$-qq#'?D4!8$-q9r   )r4   r  r  r   N)
r   r   r   r   r   rI   r   r   r
  r   r   r   r   r   r   B  s    	(')Rr   r   c                 ~     [        U 5      n[        R                  " USS9  g! [         a    [        U S5      n N.f = f)zExhaust an iterator or stream.i @  r   )maxlenN)iterr3   rp   collectionsdeque)stream_or_iterableiterators     r   r   r     sB    8*+ hq)  8/78s   # <<c                    Sn X!:  a  [        S5      eU R                  U5      nUR                  S5      nUS:w  a  O0U R                  U5        [	        U5      U:  a	  [
        0 U 4$ US-  nMi  USU nU R                  X4S-   S 5        [
        n0 nUR                  S5       H  n [        UR                  5       5      u  pU	R                  S	S
5      u  pU
R                  5        VVs0 s H  u  pXR                  5       _M     n
nnUS:X  a"  [        nU
R                  S5      (       a  [        nX4X{'   M     U[
        :X  a  U R                  U5        XgU 4$ s  snnf ! [         a     M  f = f)z@
Parse one and exactly one stream that encapsulates a boundary.
r"   z'Request max total header size exceeded.s   

r   rZ   Nrd   s   
:rX   r[   rb   )r   r|   r  r   rq   RAWr   r   decodeitemsr-   r2   rz   r+   r   )r   max_header_sizeheaders_chunk_sizer   
header_endheaderTYPEoutdictlinemain_value_pairparamsr\   valuekvs                  r   parse_boundary_streamr0    s}    
/&'PQQ ./ ZZ,
 	Uu:**V$$a' * ;JF LLA~'()DG W%	&=dkkm&L#O)//Q7KD06?amF? ((Dzz*%% &" s{U6"" @ 		s%   %AE'EEE
E*)E*c                        \ rS rSrS rS rSrg)rr   i  c                 $    Xl         SU-   U l        g )Ns   --)r   
_separatorr   s      r   rI   Parser.__init__  s    (*r   c              #      #    [        U R                  U R                  5      nU H  n[        U[        5      v   M     g 7frf   )r   r   r3  r0  MAX_TOTAL_HEADER_SIZE)r>   boundarystream
sub_streams      r   r   Parser.__iter__  s1     *4<<I(J'
4IJJ )s   =?)r3  r   N)r   r   r   r   rI   r   r   r   r   r   rr   rr     s    +Kr   rr   )*r   r`   r~   r  r   django.confr   django.core.exceptionsr   r   r   r   django.core.files.uploadhandlerr   r	   r
   django.utils.datastructuresr   django.utils.encodingr   django.utils.httpr   django.utils.regex_helperr   __all__rN   r   r   r!  r   rz   	frozensetrt   r6  r   ro   rp   r   r   r   r0  rr   r   r   r   <module>rC     s           U T 6 + 5 6
M	9 		9 	 % m% m%`t tn 0" "&] ]@*;#|	K 	Kr   