B
    CVvgˆW  ã               @   sZ  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 dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlm Z  edddid�Z!ee"ƒj#Z$G dd„ de%ƒZ&G dd„ dƒZ'd'dd„Z(e  )¡ dd„ ƒZ*dd„ Z+dd„ Z,G dd „ d ƒZ-G d!d"„ d"ƒZ.d#d$„ Z/d%d&„ Z0dS )(é    N)ÚPath)Úsettings)ÚHttp404ÚHttpResponseÚHttpResponseNotFound)ÚContextÚEngineÚTemplateDoesNotExist)Úpprint)Úresolve)Útimezone)ÚMultiValueDict)Ú	force_str)Úimport_string)Ú_lazy_re_compile)Úget_docs_versionTZi18nzdjango.templatetags.i18n)ÚdebugÚ	librariesc               @   s   e Zd ZdS )ÚExceptionCycleWarningN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú6/tmp/pip-install-o3oxmrkh/Django/django/views/debug.pyr       s   r   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚCallableSettingWrapperzÅ
    Object to wrap callable appearing in settings.
    * Not to call in the debug page (#21345).
    * Not to break the debug page if the callable forbidding to set attributes
      (#23070).
    c             C   s
   || _ d S )N)Ú_wrapped)ÚselfZcallable_settingr   r   r   Ú__init__+   s    zCallableSettingWrapper.__init__c             C   s
   t | jƒS )N)Úreprr   )r   r   r   r   Ú__repr__.   s    zCallableSettingWrapper.__repr__N)r   r   r   Ú__doc__r   r   r   r   r   r   r   $   s   r   éô  c             C   sL   t | ƒ| |||ƒ}|  d¡r2| ¡ }t||dd�S | ¡ }t||dd�S dS )z‰
    Create a technical server error response. The last three arguments are
    the values returned from sys.exc_info() and friends.
    z	text/html)ÚstatusÚcontent_typeztext/plain; charset=utf-8N)Úget_exception_reporter_classZacceptsÚget_traceback_htmlr   Úget_traceback_text)ÚrequestÚexc_typeÚ	exc_valueÚtbÚstatus_codeZreporterÚhtmlÚtextr   r   r   Útechnical_500_response2   s    
r.   c               C   s   t tjƒƒ S )N)r   r   Z!DEFAULT_EXCEPTION_REPORTER_FILTERr   r   r   r   Ú%get_default_exception_reporter_filter@   s    r/   c             C   s   t ƒ }t| d|ƒS )NZexception_reporter_filter)r/   Úgetattr)r'   Zdefault_filterr   r   r   Úget_exception_reporter_filterF   s    r1   c             C   s   t tjƒ}t| d|ƒS )NZexception_reporter_class)r   r   ZDEFAULT_EXCEPTION_REPORTERr0   )r'   Z default_exception_reporter_classr   r   r   r$   K   s    
r$   c               @   sb   e Zd ZdZdZedejd�Zdd„ Z	dd„ Z
d	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚSafeExceptionReporterFilterz‹
    Use annotations made by the sensitive_post_parameters and
    sensitive_variables decorators to filter out sensitive information.
    z********************z#API|TOKEN|KEY|SECRET|PASS|SIGNATURE)Úflagsc                s°   yˆ j  |¡}W n tk
r(   d}Y nX |r6ˆ j}nft|tƒrX‡ fdd„| ¡ D ƒ}nDt|tƒrv‡ fdd„|D ƒ}n&t|tƒr˜t‡ fdd„|D ƒƒ}n|}t	|ƒr¬t
|ƒ}|S )z¦
        Cleanse an individual setting key/value of sensitive content. If the
        value is a dictionary, recursively cleanse the keys in that dictionary.
        Fc                s   i | ]\}}ˆ   ||¡|“qS r   )Úcleanse_setting)Ú.0ÚkÚv)r   r   r   ú
<dictcomp>e   s    z?SafeExceptionReporterFilter.cleanse_setting.<locals>.<dictcomp>c                s   g | ]}ˆ   d |¡‘qS )Ú )r4   )r5   r7   )r   r   r   ú
<listcomp>g   s    z?SafeExceptionReporterFilter.cleanse_setting.<locals>.<listcomp>c                s   g | ]}ˆ   d |¡‘qS )r9   )r4   )r5   r7   )r   r   r   r:   i   s    )Úhidden_settingsÚsearchÚ	TypeErrorÚcleansed_substituteÚ
isinstanceÚdictÚitemsÚlistÚtupleÚcallabler   )r   ÚkeyÚvalueZis_sensitiveÚcleansedr   )r   r   r4   X   s     



z+SafeExceptionReporterFilter.cleanse_settingc             C   s8   i }x.t tƒD ]"}| ¡ r|  |tt|ƒ¡||< qW |S )z‡
        Return a dictionary of the settings module with values of sensitive
        settings replaced with stars (*********).
        )Údirr   Úisupperr4   r0   )r   Zsettings_dictr6   r   r   r   Úget_safe_settingsr   s
    z-SafeExceptionReporterFilter.get_safe_settingsc                s&   t |dƒsi S ‡ fdd„|j ¡ D ƒS )zU
        Return a dictionary of request.META with sensitive values redacted.
        ÚMETAc                s   i | ]\}}ˆ   ||¡|“qS r   )r4   )r5   r6   r7   )r   r   r   r8   ƒ   s    zESafeExceptionReporterFilter.get_safe_request_meta.<locals>.<dictcomp>)ÚhasattrrK   rA   )r   r'   r   )r   r   Úget_safe_request_meta}   s    
z1SafeExceptionReporterFilter.get_safe_request_metac             C   s
   t jdkS )a  
        This filter is to add safety in production environments (i.e. DEBUG
        is False). If DEBUG is True then your site is not safe anyway.
        This hook is provided as a convenience to easily activate or
        deactivate the filter on a per request basis.
        F)r   ÚDEBUG)r   r'   r   r   r   Ú	is_active…   s    z%SafeExceptionReporterFilter.is_activec             C   sF   t |dg ƒ}|  |¡rB|rB| ¡ }x|D ]}||kr(| j||< q(W |S )zç
        Replace the keys in a MultiValueDict marked as sensitive with stars.
        This mitigates leaking sensitive POST parameters if something like
        request.POST['nonexistent_key'] throws an exception (#21098).
        Úsensitive_post_parameters)r0   rO   Úcopyr>   )r   r'   ZmultivaluedictrP   Úparamr   r   r   Úget_cleansed_multivaluedictŽ   s    
z7SafeExceptionReporterFilter.get_cleansed_multivaluedictc             C   s„   |dkri S t |dg ƒ}|  |¡rz|rz|j ¡ }|dkrTx|D ]}| j||< q>W |S x|D ]}||krZ| j||< qZW |S n|jS dS )zk
        Replace the values of POST parameters marked as sensitive with
        stars (*********).
        NrP   Ú__ALL__)r0   rO   ÚPOSTrQ   r>   )r   r'   rP   rG   r6   rR   r   r   r   Úget_post_parametersœ   s    


z/SafeExceptionReporterFilter.get_post_parametersc          
   C   sN   yt |tƒ}W n* tk
r8 } zd ||¡S d }~X Y nX |rJ|  ||¡}|S )Nz{!r} while evaluating {!r})r?   r   Ú	ExceptionÚformatrS   )r   r'   rF   Zis_multivalue_dictÚer   r   r   Úcleanse_special_typesµ   s    z1SafeExceptionReporterFilter.cleanse_special_typesc       	      C   s  |j }d}x@|dk	rJ|jjdkrBd|jkrB|jd }t|ddƒ}P |j }qW i }|  |¡rÀ|rÀ|dkr‚xV|jD ]}| j||< qnW qèxd|j ¡ D ],\}}||kr¦| j}n|  ||¡}|||< qŽW n(x&|j ¡ D ]\}}|  ||¡||< qÌW |jjdk�rd|jk�r| j|d< | j|d< | ¡ S )ze
        Replace the values of variables marked as sensitive with
        stars (*********).
        NZsensitive_variables_wrapperÚsensitive_variablesrT   Ú	func_argsZfunc_kwargs)	Úf_backÚf_codeÚco_nameÚf_localsr0   rO   r>   rA   rZ   )	r   r'   Útb_frameÚcurrent_framer[   ÚwrapperrG   ÚnamerF   r   r   r   Úget_traceback_frame_variablesÃ   s4    





z9SafeExceptionReporterFilter.get_traceback_frame_variablesN)r   r   r   r    r>   r   ÚreÚIr;   r4   rJ   rM   rO   rS   rV   rZ   re   r   r   r   r   r2   P   s   	r2   c               @   st   e Zd ZdZedd„ ƒZedd„ ƒZddd„Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zddd„Zdd„ Zdd„ Zdd„ ZdS )ÚExceptionReporterz0Organize and coordinate reporting on exceptions.c             C   s   t d d S )NÚ	templatesztechnical_500.html)ÚCURRENT_DIR)r   r   r   r   Úhtml_template_pathù   s    z$ExceptionReporter.html_template_pathc             C   s   t d d S )Nri   ztechnical_500.txt)rj   )r   r   r   r   Útext_template_pathý   s    z$ExceptionReporter.text_template_pathFc             C   sJ   || _ t| j ƒ| _|| _|| _|| _|| _t| jdd ƒ| _d| _	d | _
d S )NZtemplate_debugF)r'   r1   Úfilterr(   r)   r*   Úis_emailr0   Útemplate_infoÚtemplate_does_not_existÚ
postmortem)r   r'   r(   r)   r*   rn   r   r   r   r     s    zExceptionReporter.__init__c             C   sh  | j r*t| j tƒr*d| _| jjp&| jg| _|  ¡ }x€t|ƒD ]t\}}d|kr¨g }xN|d D ]B\}}t	|ƒ}t
|ƒdkrŽd|dd… t
|ƒf }| ||f¡ qZW ||d< |||< q<W d}| j �r8t| j tƒ�r8t| jddƒ}t| jd	dƒ}	|dk	�r8|	dk	�r8| jjd
 }
t|
t|d dƒt|	d t
|
ƒƒ… ddd�}ddlm} | jdk�rVd}n,yt| jjƒ}W n tk
�r€   d}Y nX | j||| j| j | j¡|t| j | j¡ ¡ ƒ| j ¡ tj dtj!dd…  t" #¡ |ƒ tj$| j%| j| jdœ}| jdk	�r(| jj& ¡ |d< | jj' ¡ |d< | jj( ¡ |d< | j �r<| j j)|d< | j�rRt| jƒ|d< |�rd|d |d< |S )z5Return a dictionary containing traceback information.TÚvarsi   u   %sâ€¦ <trimmed %d bytes string>r   r9   ÚstartNÚendé   é   ÚasciiÚreplace)Úerrors)Úget_versionz%[unable to retrieve the current user]z%d.%d.%dé   )rn   Úunicode_hintÚframesr'   Zrequest_metaÚuser_strZfiltered_POST_itemsr   Zsys_executableZsys_version_infoZserver_timeZdjango_version_infoÚsys_pathro   rp   rq   Zrequest_GET_itemsZrequest_FILES_itemsZrequest_COOKIES_itemsZexception_typeZexception_valueéÿÿÿÿZ	lastframe)*r(   Ú
issubclassr	   rp   r)   Úchainrq   Úget_traceback_framesÚ	enumerater
   ÚlenÚappendÚUnicodeErrorr0   Úargsr   ÚmaxÚminÚdjangorz   r'   ÚstrÚuserrW   rn   rm   rM   rB   rV   rA   rJ   ÚsysÚ
executableÚversion_infor   ÚnowÚpathro   ÚGETZFILESZCOOKIESr   )r   r}   ÚiÚframeZ
frame_varsr6   r7   r|   rs   rt   Zunicode_strrz   r~   Úcr   r   r   Úget_traceback_data  sr    "


z$ExceptionReporter.get_traceback_datac          	   C   sB   | j jdd��}t | ¡ ¡}W dQ R X t|  ¡ dd�}| |¡S )z1Return HTML version of debug 500 HTTP error page.zutf-8)ÚencodingNF)Úuse_l10n)rk   ÚopenÚDEBUG_ENGINEÚfrom_stringÚreadr   r—   Úrender)r   ÚfhÚtr–   r   r   r   r%   U  s    z$ExceptionReporter.get_traceback_htmlc          	   C   sD   | j jdd��}t | ¡ ¡}W dQ R X t|  ¡ ddd�}| |¡S )z7Return plain text version of debug 500 HTTP error page.zutf-8)r˜   NF)Z
autoescaper™   )rl   rš   r›   rœ   r�   r   r—   rž   )r   rŸ   r    r–   r   r   r   r&   \  s    z$ExceptionReporter.get_traceback_textc          	   C   sŠ   d }t |dƒrBy| |¡}W n tk
r0   Y nX |d k	rB| ¡ }|d kr†y&t|dƒ�}| ¡  ¡ }W d Q R X W n tk
r„   Y nX |S )NÚ
get_sourceÚrb)rL   r¡   ÚImportErrorÚ
splitlinesrš   r�   ÚOSError)r   ÚfilenameÚloaderÚmodule_nameÚsourceÚfpr   r   r   Ú_get_sourcec  s    
zExceptionReporter._get_sourceNc                sä   |   |||¡}|dkr"dg dg fS t|d tƒr|d‰ x4|dd… D ]$}t d|¡}|rB|d  d¡‰ P qBW ‡ fdd„|D ƒ}td|| ƒ}	|| }
y(||	|… }|| }||d |
… }W n tk
rÖ   dg dg fS X |	|||fS )	z—
        Return context_lines before and after lineno from file.
        Return (pre_context_lineno, pre_context, context_line, post_context).
        Nr   rw   é   s   coding[:=]\s*([-\w.]+)ru   c                s   g | ]}t |ˆ d ƒ‘qS )rx   )rŒ   )r5   Úsline)r˜   r   r   r:   ‰  s    z:ExceptionReporter._get_lines_from_file.<locals>.<listcomp>)r«   r?   Úbytesrf   r<   Údecoder‰   Ú
IndexError)r   r¦   ÚlinenoZcontext_linesr§   r¨   r©   ÚlineÚmatchZlower_boundZupper_boundÚpre_contextÚcontext_lineÚpost_contextr   )r˜   r   Ú_get_lines_from_filet  s(    z&ExceptionReporter._get_lines_from_filec             C   s4   t |dd ƒ}t |dd ƒ}t |dd ƒ}|p2|r0d S |S )NÚ	__cause__Ú__suppress_context__Ú__context__)r0   )r   r)   ÚexplicitZsuppress_contextZimplicitr   r   r   Ú_get_explicit_or_implicit_cause–  s    z1ExceptionReporter._get_explicit_or_implicit_causec             C   s¬   g }| j }x6|r@| |¡ |  |¡}||krt d| t¡ P qW g }|sN|S | ¡ }|s`| jn|j}x@| 	|  
||¡¡ y| ¡ }W n tk
rœ   P Y nX |j}qhW |S )NzHCycle in the exception chain detected: exception '%s' encountered again.)r)   r†   r¼   ÚwarningsÚwarnr   Úpopr*   Ú__traceback__ÚextendÚget_exception_traceback_framesr°   )r   Ú
exceptionsr)   r}   r*   r   r   r   rƒ   œ  s0    


z&ExceptionReporter.get_traceback_framesc             c   s  |   |¡}t|ddƒ}|d kr.||d ddœV  xä|d k	�r|jj d¡rP|j}q0|jjj}|jjj}|j	d }|jj
 d¡}|jj
 d¡pŒd	}	|  ||d
||	¡\}
}}}|
d krÀ|}
g }d}g }||||	 d¡rÔdnd|||d | j | j|j¡t|ƒ||||
d dœV  |j}q0W d S )Nr¸   Tr�   )Ú	exc_causeÚexc_cause_explicitr*   ÚtypeZ__traceback_hide__ru   Ú
__loader__r   r9   é   z<source code not available>zdjango.r‹   )rÄ   rÅ   r*   rÆ   r¦   Úfunctionr±   rr   Úidr´   rµ   r¶   Úpre_context_lineno)r¼   r0   ra   r`   ÚgetÚtb_nextr^   Úco_filenamer_   Ú	tb_linenoÚ	f_globalsr·   Ú
startswithrm   re   r'   rÊ   )r   r)   r*   rÄ   rÅ   r¦   rÉ   r±   r§   r¨   rË   r´   rµ   r¶   r   r   r   rÂ   ½  sJ    




z0ExceptionReporter.get_exception_traceback_frames)F)NN)r   r   r   r    Úpropertyrk   rl   r   r—   r%   r&   r«   r·   r¼   rƒ   rÂ   r   r   r   r   rh   ö   s   
H
"!rh   c             C   s   y|j d d }W n( tttfk
r:   | jdd… }Y nX y|j d d }W n0 tttfk
r~   d}| jrv| jjnd}Y npX d}|ræ| jdkrît|ƒdkrît|d ƒdkrît	|d d d	d
ƒt	|d d dd
ƒ  krâdkrîn nt
| ƒS t	| dtjƒ}t|tjƒ�r|j}d
}yt| jƒ}W n tk
�r8   Y n\X |j}t|dƒ�rT|j}n"t|dƒ�rvt|jdƒ�rv|jj}t|dƒ�r”|j}	d|	|f }ttddƒjdd��}
t |
 ¡ ¡}W dQ R X tƒ }t|tj|||t|ƒ| |  ¡ |dœ	ƒ}t!| "|¡dd�S )zBCreate a technical 404 error response. `exception` is the Http404.r   r’   ru   NÚtriedTFú/Zapp_namer9   Ú	namespaceZadminÚurlconfr   Ú	__class__r   z%s.%sri   ztechnical_404.htmlzutf-8)r˜   )	rÖ   Zroot_urlconfÚrequest_pathZurlpatternsÚresolvedÚreasonr'   r   Zraising_view_namez	text/html)r#   )#rˆ   r°   r=   ÚKeyErrorZ	path_infoÚresolver_matchrÓ   r’   r…   r0   Údefault_urlconfr   ZROOT_URLCONFr?   ÚtypesÚ
ModuleTyper   r   r   ÚfuncrL   r×   r   r   rj   rš   r›   rœ   r�   r/   r   rŒ   rJ   r   rž   )r'   Ú	exceptionZ	error_urlrÓ   rÙ   rÖ   ZcallerrÜ   ÚobjÚmodulerŸ   r    Zreporter_filterr–   r   r   r   Útechnical_404_responseì  s\    
8
rä   c          	   C   sN   t tddƒjdd��}t | ¡ ¡}W dQ R X tdtƒ iƒ}t| 	|¡dd�S )	z+Create an empty URLconf 404 error response.ri   zdefault_urlconf.htmlzutf-8)r˜   NÚversionz	text/html)r#   )
r   rj   rš   r›   rœ   r�   r   r   r   rž   )r'   rŸ   r    r–   r   r   r   rÝ   (  s
    rÝ   )r!   )1Ú	functoolsrf   rŽ   rÞ   r½   Zpathlibr   Zdjango.confr   Zdjango.httpr   r   r   Zdjango.templater   r   r	   Zdjango.template.defaultfiltersr
   Zdjango.urlsr   Zdjango.utilsr   Zdjango.utils.datastructuresr   Zdjango.utils.encodingr   Zdjango.utils.module_loadingr   Zdjango.utils.regex_helperr   Zdjango.utils.versionr   r›   Ú__file__Úparentrj   ÚUserWarningr   r   r.   Ú	lru_cacher/   r1   r$   r2   rh   rä   rÝ   r   r   r   r   Ú<module>   s@   

 ' w<