U
    aa                     @   s,  d Z ddlZddlZddlZddlZddl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mZ ddlmZ ddlmZ d	ZG d
d deZG dd deZdZdZdZG dd dZG dd dZG dd dZG dd dZ G dd dZ!dd Z"dd Z#G dd  d Z$d!d" Z%d#d$ Z&dS )%z
Multi-part parsing for file uploads.

Exposes one class, ``MultiPartParser``, which feeds chunks of uploaded data to
file upload handlers for processing.
    N)unquote)settings)RequestDataTooBigSuspiciousMultipartFormTooManyFieldsSent)SkipFileStopFutureHandlers
StopUpload)MultiValueDict)	force_str)MultiPartParserMultiPartParserErrorInputStreamExhaustedc                   @   s   e Zd ZdS )r   N)__name__
__module____qualname__ r   r   /home/adriano.carvalho/ftp/files/BrinquedotecaVirtual/brinquedotecavirtual/venv/lib/python3.8/site-packages/django/http/multipartparser.pyr      s   r   c                   @   s   e Zd ZdZdS )r   z5
    No more reads are allowed from this device.
    N)r   r   r   __doc__r   r   r   r   r      s   r   rawfilefieldc                   @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )r   z
    A rfc2388 multipart/form-data parser.

    ``MultiValueDict.parse()`` reads the input stream in ``chunk_size`` chunks
    and returns a tuple of ``(MultiValueDict(POST), MultiValueDict(FILES))``.
    Nc              	   C   s.  | dd}|ds"td| zt|d\}}W n$ tk
r\   tdt| Y nX | d}|rvt|stdt| zt	| d	d
}	W n t
tfk
r   d
}	Y nX |	d
k rtd|	 t|tr|d}|| _|| _dd |D }
tdg|
 | _|| _|ptj| _|	| _|| _dS )a  
        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: %rc                 S   s   g | ]}|j r|j qS r   )
chunk_size).0xr   r   r   
<listcomp>`   s      z,MultiPartParser.__init__.<locals>.<listcomp>iN)get
startswithr   parse_headerencodeUnicodeEncodeErrorr   cgivalid_boundaryint
ValueError	TypeError
isinstancestr	_boundary_input_datamin_chunk_size_metar   DEFAULT_CHARSET	_encoding_content_length_upload_handlers)selfZMETAZ
input_dataZupload_handlersencodingcontent_typectypesoptsr   content_lengthZpossible_sizesr   r   r   __init__2   s4    




zMultiPartParser.__init__c           !      C   s  ddl m} | j}| j}| jdkr4|| jdt fS |D ]:}|| j| j| j| j	|}|dk	r8|d |d f  S q8|dd| _
t | _tt| j| j}d}dgt| }d}	d}
d}zt|| j	D ]\}}}|r| || d}z|d d }|d	  }W n  tttfk
r$   Y qY nX |d
}|dk	rF|d  }t||dd}|tkrN|
d7 }
tjdk	rtj|
k rtdtjdk	rtj|	 }|dkr|j|d}|	t|7 }	zt|}W n t j!k
r   |}Y nX n|j|d}|	t|7 }	|	t|d 7 }	tjdk	r4|	tjkr4t"d| j
#|t||dd q|t$krf|d}|rt||dd}| %t&'|}|sq|ddi f\}}| }|d}zt(|dd }W n  tt)t*fk
r   d}Y nX dgt| }z<|D ]>}z|+|||||| W n t,k
r<   Y  qBY nX q|D ]}|dkrd-|. }t|d }|dkr|d| }|d-|. 7 }t|d }qnzt|}W n. t/k
r } zt0d|W 5 d}~X Y nX t1|D ]B\}}t|}|2||| }||  |7  < |dkr qFqqFW n& t3k
r^   | 4  t5| Y nX |}qt5| qW n> t6k
r }  z| 4  | j7st5| j W 5 d} ~ X Y nX t5| j t8dd |D  d| j
_9| j
| jfS )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r7   N   T)Zmutablecontent-dispositionnamezcontent-transfer-encodingreplaceerrorszRThe number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.base64)size   z;Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.filenamezcontent-typer   charsetzcontent-length       zCould not decode base64 data.c                 s   s   | ]}|  V  qd S N)Zupload_complete)r   handlerr   r   r   	<genexpr>  s     z(MultiPartParser.parse.<locals>.<genexpr>F):Zdjango.httpr=   r3   r5   r4   r
   Zhandle_raw_inputr.   r1   r-   _post_files
LazyStream	ChunkIterr0   lenParserhandle_file_completestripKeyError
IndexErrorAttributeErrorr!   r   FIELDr   ZDATA_UPLOAD_MAX_NUMBER_FIELDSr   ZDATA_UPLOAD_MAX_MEMORY_SIZEreadrE   	b64decodebinasciiErrorr   
appendlistFILEIE_sanitizehtmlunescaper(   r*   r)   Znew_filer   joinsplit	Exceptionr   	enumerateZreceive_data_chunkr   _close_filesexhaustr	   Zconnection_resetanyZ_mutable)!r6   r=   r7   handlersrM   resultstreamold_field_namecountersZnum_bytes_readZnum_post_keys	read_sizeZ	item_typeZ	meta_dataZfield_streamdisposition
field_nameZtransfer_encodingraw_datadata	file_namer8   Zcontent_type_extrarI   r;   chunkZstripped_chunk	remainingZ
over_chunkexciZchunk_lengther   r   r   parseh   s    










    



zMultiPartParser.parsec                 C   sH   t | jD ]8\}}||| }|r
| jt|| jdd|  qDq
dS )zT
        Handle all the signaling that takes place when a file is complete.
        rB   rC   N)rg   r5   Zfile_completerP   r_   r   r3   )r6   rn   ro   ry   rM   Zfile_objr   r   r   rU   !  s
    z$MultiPartParser.handle_file_completec                 C   s   |o|| dd d  S )z3Cleanup filename from Internet Explorer full paths.\r?   N)rfindrV   )r6   rH   r   r   r   ra   ,  s    zMultiPartParser.IE_sanitizec                 C   s$   | j D ]}t|dr|j  qd S )Nr   )r5   hasattrr   close)r6   rM   r   r   r   rh   0  s    

zMultiPartParser._close_files)N)	r   r   r   r   r<   r{   rU   ra   rh   r   r   r   r   r   +   s   
6 :r   c                   @   sT   e Zd ZdZdddZdd ZdddZd	d
 Zdd Zdd Z	dd Z
dd ZdS )rQ   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                 C   s.   || _ d| _d| _|| _d| _|| _g | _dS )z
        Every LazyStream must have a producer when instantiated.

        A producer is an iterable that returns a string each time it
        is called.
        FrJ   r   N)	_producer_empty	_leftoverlengthposition
_remaining_unget_history)r6   Zproducerr   r   r   r   r<   A  s    zLazyStream.__init__c                 C   s   | j S rL   )r   r6   r   r   r   tellP  s    zLazyStream.tellc                    s    fdd}d | S )Nc                  3   s   d kr j n} | d kr*d V  d S | dkr| dksBtdzt }W n tk
rd   Y d S X |d |  } || d   | t|8 } |V  q*d S )NrJ   r   z0remaining bytes to read should never go negative)r   rd   AssertionErrornextStopIterationungetrS   )rw   rv   Zemittingr6   rF   r   r   partsT  s    zLazyStream.read.<locals>.partsrJ   )rd   )r6   rF   r   r   r   r   r[   S  s    zLazyStream.readc                 C   s:   | j r| j }d| _ nt| j}g | _|  jt|7  _|S )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.
        rJ   )r   r   r   r   r   rS   )r6   outputr   r   r   __next__m  s    
zLazyStream.__next__c                 C   s
   g | _ dS )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   r   r   r   r   }  s    zLazyStream.closec                 C   s   | S rL   r   r   r   r   r   __iter__  s    zLazyStream.__iter__c                 C   s8   |sdS |  t| |  jt|8  _|| j | _dS )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_historyrS   r   r   )r6   bytesr   r   r   r     s
    zLazyStream.ungetc                    sB    g| j dd  | _ t fdd| j D }|dkr>tddS )aZ  
        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   c                    s   g | ]}| kr|qS r   r   )r   Zcurrent_number	num_bytesr   r   r      s   z4LazyStream._update_unget_history.<locals>.<listcomp>(   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   rS   r   )r6   r   Znumber_equalr   r   r   r     s    z LazyStream._update_unget_history)N)N)r   r   r   r   r<   r   r[   r   r   r   r   r   r   r   r   r   rQ   9  s   

	rQ   c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )rR   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                 C   s   || _ || _d S rL   )flor   )r6   r   r   r   r   r   r<     s    zChunkIter.__init__c                 C   s@   z| j | j}W n tk
r,   t Y nX |r6|S t d S rL   )r   r[   r   r   r   )r6   rt   r   r   r   r     s    zChunkIter.__next__c                 C   s   | S rL   r   r   r   r   r   r     s    zChunkIter.__iter__N)r   )r   r   r   r   r<   r   r   r   r   r   r   rR     s   

rR   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	InterBoundaryIterz7
    A Producer that will iterate over boundaries.
    c                 C   s   || _ || _d S rL   )_streamr-   r6   rm   r   r   r   r   r<     s    zInterBoundaryIter.__init__c                 C   s   | S rL   r   r   r   r   r   r     s    zInterBoundaryIter.__iter__c                 C   s4   zt t| j| jW S  tk
r.   t Y nX d S rL   )rQ   BoundaryIterr   r-   r   r   r   r   r   r   r     s    zInterBoundaryIter.__next__N)r   r   r   r   r<   r   r   r   r   r   r   r     s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   ae  
    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                 C   sF   || _ || _d| _t|d | _| j d}|s6t | j | d S )NF   r?   )r   r-   _donerS   	_rollbackr[   r   r   )r6   rm   r   Zunused_charr   r   r   r<     s    zBoundaryIter.__init__c                 C   s   | S rL   r   r   r   r   r   r     s    zBoundaryIter.__iter__c           
      C   s   | j rt | j}| j}d}g }|D ].}|t|7 }|| ||krJ qZ|s$ qZq$d| _ |sdt d|}| |}|r|\}}	|||	d   d| _ |d | S |d |  sd| _ |S ||| d   |d |  S d S )Nr   TrJ   )	r   r   r   r   rS   appendrd   _find_boundaryr   )
r6   rm   rollback
bytes_readchunksr   rv   r   endr   r   r   r   r     s8    


zBoundaryIter.__next__c                 C   s   | | j}|dk rdS |}|t| j }td|d }|||d  dkrT|d8 }td|d }|||d  dkr~|d8 }||fS dS )a  
        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   Nr?      
   )findr-   rS   max)r6   rt   indexr   r   lastr   r   r   r     s    	zBoundaryIter._find_boundaryN)r   r   r   r   r<   r   r   r   r   r   r   r   r     s
   )r   c                 C   s>   zt | }W n tk
r*   t| d}Y nX tj|dd dS )zExhaust an iterator or stream.i @  r   )maxlenN)iterr*   rR   collectionsdeque)Zstream_or_iterableiteratorr   r   r   ri   5  s
    ri   c              	   C   s   |  |}|d}dd }|dkr8| | ti | fS |d| }| ||d d  t}i }|dD ]X}z||\}	\}
}W n tk
r   Y qlY nX |	dkrt}|d	rt}|
|f||	< ql|tkr| | ||| fS )
zH
    Parse one and exactly one stream that encapsulates a boundary.
    s   

c                 S   sN   t | \}}z|dd\}}W n  tk
r@   td|  Y nX |||ffS )N:r?   zInvalid header: %r)r#   re   r)   )lineZmain_value_pairparamsrA   valuer   r   r   _parse_headerL  s    z,parse_boundary_stream.<locals>._parse_headerNrK   s   
r@   rH   )	r[   r   r   RAWre   r)   rZ   r!   r`   )rm   Zmax_header_sizerv   Z
header_endr   headerZTYPEZoutdictr   rA   r   r   r   r   r   parse_boundary_stream>  s.    






r   c                   @   s   e Zd Zdd Zdd ZdS )rT   c                 C   s   || _ d| | _d S )Ns   --)r   
_separatorr   r   r   r   r<   z  s    zParser.__init__c                 c   s(   t | j| j}|D ]}t|dV  qd S )Ni   )r   r   r   r   )r6   ZboundarystreamZ
sub_streamr   r   r   r   ~  s    zParser.__iter__N)r   r   r   r<   r   r   r   r   r   rT   y  s   rT   c                 C   s*  t d|  }|d d}i }|D ]}|d}|dkr(d}|d|   d}|dr|dd }|d	d
krd}||d d  }|r|d	\}	}
}t	| |	 d}t
|d
kr|dd |dd   krdkrn n |dd }|dddd}|||< q(||fS )z
    Parse the header into a key-value.

    Input (line): bytes, output: str for key/name, bytes for values which
    will be decoded later.
       ;r   r      =FN*r      'rG   Tr?   r>      "s   \\   \s   \")_parse_header_paramspoplowerdecoder   rV   endswithcountre   r   rS   rB   )r   plistkeypdictpry   Zhas_encodingrA   r   r7   langr   r   r   r#     s*    

8
r#   c                 C   s   g }| d d dkr| dd  } |  d}|dkrV| dd|d rV|  d|d }q*|dk rft| }| d | }||  | |d  } q|S )Nr?   r   r   r   rG   )r   r   rS   r   rV   )sr   r   fr   r   r   r     s    
r   )'r   rE   r]   r&   r   rb   urllib.parser   Zdjango.confr   Zdjango.core.exceptionsr   r   r   Zdjango.core.files.uploadhandlerr   r   r	   Zdjango.utils.datastructuresr
   Zdjango.utils.encodingr   __all__rf   r   r   r   r`   rZ   r   rQ   rR   r   r   ri   r   rT   r#   r   r   r   r   r   <module>   s:     s`	; 