
    >/iC                        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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  S SKJr  S SKJr  S SKJr  S S	KJr  \R0                  " \5      r\R6                  " S
5      r\R6                  " S\R:                  5      rSr " S S5      r  SS jr! SS jr"S r#S r$S r%S r&S r'g)    N)progress)	constants)extension_loader)issue)meta_ast)metrics)node_visitor)test_setz!#\s*nosec:?\s*(?P<tests>[^#]+)?#?z(?:(B\d+|[a-z\d_]+),?)+2   c                       \ rS rSr/ r     SS jrS r\R                  \R                  4S jr	S r
S r\R                  \R                  4S jr SS	 jrSS
 jrS rS rS rSrg)BanditManager    Nc                 P   X0l         X@l        XPl        U(       d  0 nXpl        Xl        / U l        / U l        [        R                  " 5       U l	        / U l
        / U l        / U l        X l        [        R                  " 5       U l        [         R"                  " X5      U l        / U l        g)a  Get logger, config, AST handler, and result store ready

:param config: config options object
:type config: bandit.core.BanditConfig
:param agg_type: aggregation type
:param debug: Whether to show debug messages or not
:param verbose: Whether to show verbose output
:param quiet: Whether to only show output in the case of an error
:param profile_name: Optional name of profile to use (from cmd line)
:param ignore_nosec: Whether to ignore #nosec or not
:return:
N)debugverbosequietignore_nosecb_conf
files_listexcluded_files
b_meta_astBanditMetaAstb_maskippedresultsbaselineagg_typer   Metrics
b_test_setBanditTestSetb_tsscores)selfconfigr   r   r   r   profiler   s           M/home/james-whalen/.local/lib/python3.13/site-packages/bandit/core/manager.py__init__BanditManager.__init__#   s    , 

G( ,,.	 (,,V=	    c                     / nU R                    HV  n[        US   [        5      (       a*  UR                  US   R	                  S5      US   45        ME  UR                  U5        MX     U$ )Nr   zutf-8   )r   
isinstancebytesappenddecode)r#   retskips      r&   get_skippedBanditManager.get_skippedK   s[    LLD$q'5))

DGNN73T!W=>

4 	 !
 
r)   c                 $    U R                  X5      $ N)filter_results)r#   	sev_level
conf_levels      r&   get_issue_listBanditManager.get_issue_listU   s     ""999r)   c                     / n [         R                  " U5      nUS    Vs/ s H  n[        R                  " U5      PM     nnX l        gs  snf ! [         a   n[
        R                  SU5         SnAN1SnAff = f)zPopulate a baseline set of issues from a JSON report

This will populate a list of baseline issues discovered from a previous
run of bandit. Later this baseline can be used to filter out the result
set, see filter_results.
r   z Failed to load baseline data: %sN)jsonloadsr   issue_from_dict	ExceptionLOGwarningr   )r#   dataitemsjdatajes         r&   populate_baselineBanditManager.populate_baselineZ   sq     	?JJt$E7<Y7GH7G!U**1-7GEH  I 	?KK:A>>	?s(   A  A
A 
A 
A9A44A9c                     U R                    Vs/ s H  o3R                  X5      (       d  M  UPM     nnU R                  (       d  U$ [        U R                  U5      n[	        XT5      $ s  snf )a  Returns a list of results filtered by the baseline

This works by checking the number of results returned from each file we
process. If the number of results is different to the number reported
for the same file in the baseline, then we return all results for the
file. We can't reliably return just the new results, as line numbers
will likely have changed.

:param sev_filter: severity level filter to apply
:param conf_filter: confidence level filter to apply
)r   filterr   _compare_baseline_results_find_candidate_matches)r#   
sev_filterconf_filterir   	unmatcheds         r&   r6   BanditManager.filter_resultsi   s]     ||
#!xx
'HA| 	 
 }}N-dmmWE	 'y::
s
   A(A(c                 6    [        U R                  X5      5      $ )zReturn the count of results

:param sev_filter: Severity level to filter lower
:param conf_filter: Confidence level to filter
:return: Number of results in the set
)lenr9   )r#   rM   rN   s      r&   results_countBanditManager.results_count   s     4&&z?@@r)   c           	          [         R                  R                  nXW;  aX  [        R                  R                  5       (       a3  [        R                  " S5      c  [        R                  " S5      S:w  a  SOSnXu   nUR                  n	US:X  a  U	" U UUUUS9  gU	" U UUUUS	9  g! [         a  n
[        S
U S[        U
5       35      eSn
A
ff = f)a  Outputs results from the result store

:param lines: How many surrounding lines to show per result
:param sev_level: Which severity levels to show (LOW, MEDIUM, HIGH)
:param conf_level: Which confidence levels to show (LOW, MEDIUM, HIGH)
:param output_file: File to store results
:param output_format: output format plugin name
:param template: Output template with non-terminal tags <N>
                 (default:  {abspath}:{line}:
                 {test_id}[bandit]: {severity}: {msg})
:return: -
NO_COLORNTERMdumbscreentxtcustom)fileobjr7   r8   template)r]   r7   r8   lineszUnable to output report using 'z' formatter: )r   MANAGERformatters_mgrsysstdoutisattyosgetenvpluginr?   RuntimeErrorstr)r#   r_   r7   r8   output_fileoutput_formatr^   ra   	formatterreport_funcrF   s              r&   output_resultsBanditManager.output_results   s    *$	-55DDN2 

))++IIj19IIf-7	    '5I#**K('')% '')  	!?-Ax9 	s   BB% 
B% %
C/C		Cc                    [        5       n[        5       nU R                  R                  S5      =(       d    / nU R                  R                  S5      =(       d    S/nU(       am  UR                  S5       HX  n[        R
                  R                  U5      (       a   [        R
                  R                  US5      nUR                  U5        MZ     U H  n	[        R
                  R                  U	5      (       aP  U(       a1  [        U	UUS9u  pUR                  U
5        UR                  U5        M_  [        R                  SU	5        Mw  [        U	UUSS	9(       a9  U	S
:w  a   [        R
                  R                  SU	5      n	UR                  U	5        M  UR                  U	5        M     [        U5      U l        [        U5      U l        g)zAdd tests directly and from a directory to the test set

:param targets: The command line list of files and directories
:param recursive: True/False - whether to add all files from dirs
:return:
exclude_dirsinclude*.py,*)included_globsexcluded_path_stringsz5Skipping directory (%s), use -r flag to scan contentsF)enforce_glob-.N)setr   
get_optionsplitre   pathisdirjoinr.   _get_files_from_dirupdater@   rA   _is_file_includedaddsortedr   r   )r#   targets	recursiveexcluded_pathsr   r   excluded_path_globsrv   r~   fname	new_filesnewly_excludeds               r&   discover_filesBanditManager.discover_files   sj    U
"kk44^DJ//	:Fvh &,,S177==&&77<<c2D#**40	 2 Eww}}U##0C'5.A1-I
 %%i0")).9KK( %"'!&	 | "S% 8NN5)"&&u-A D !,$^4r)   c                    [        U R                  5      n[        U R                  5      [        :  aG  [        R                  5       [        R                  ::  a!  [        R                  " U R                  5      nOU R                  n[        U5       H  u  p4[        R                  SU5         US:X  a  [        R                  " [        R                  R!                  5       SS5      n["        R$                  " UR'                  5       5      nU Vs/ s H  owS:X  a  SOUPM     nnU R)                  SXa5        M  [+        US5       nU R)                  XFU5        SSS5        M     Xl        U R6                  R9                  5         gs  snf ! , (       d  f       GM  = f! [,         aC  nU R.                  R1                  XHR2                  45        UR5                  U5         SnAGMS  SnAff = f)z0Runs through all files in the scope

:return: -
zworking on file : %sry   rbr   z<stdin>N)listr   rS   PROGRESS_THRESHOLDr@   getEffectiveLevelloggingINFOr   track	enumerater   re   fdopenrb   stdinfilenoioBytesIOread_parse_fileopenOSErrorr   r.   strerrorremover   	aggregate)	r#   new_files_listfilescountr   open_fdfdataxrF   s	            r&   	run_testsBanditManager.run_tests  sn    doo. #55%%'7<<7NN4??3EOOE%e,LEII,e4-C< ii		(8(8(:D!DGJJw||~6E>L&>L#X	14n # & $$YFeT*e((~F +* -& ) 	 &
 +* -##UJJ$78%%e,,-sO   -A"FF"F8FF	FF	
F	FF
G)&7G$$G)c                     UR                  5       nUR                  5       nU R                  R                  U5        U R                  R	                  U5        [        5       n UR                  S5        [        R                  " UR                  5      nU R                  (       d4  U H.  u  pu  n
    nU[        R                  :X  d  M!  [        U	5      Xj'   M0     U R                  XXF5      nU R                  R                  U5        U R                  R!                  U/5        g ! [        R                   a     N`f = f! ["         a    [$        R&                  " S5         g [(         a1    U R*                  R                  US45        UR-                  U5         g [.         a  n[0        R3                  SU5        [0        R5                  [6        R8                  5      (       d  [0        R3                  SU5        U R*                  R                  US45        UR-                  U5        [0        R;                  SU5        [0        R;                  S[<        R>                  " 5       5         S nAg S nAff = f)	Nr      z(syntax error while parsing AST from filez3Exception occurred when executing tests against %s.z2Run "bandit --debug %s" to see the full traceback.zexception while scanning filez  Exception string: %sz  Exception traceback: %s) r   
splitlinesr   begin
count_locsdictseektokenizereadliner   COMMENT_parse_nosec_comment
TokenError_execute_ast_visitorr"   r.   count_issuesKeyboardInterruptrb   exitSyntaxErrorr   r   r?   r@   errorisEnabledForr   DEBUGr   	traceback
format_exc)r#   r   r   r   rB   r_   nosec_linestokenstoktypetokvallineno_scorerF   s                 r&   r   BanditManager._parse_file-  s   *	K::<DOO%ELLu%LL##E* &K


1!**5>>:((>D:&!a"h&6&662Fv2NK/ ?E --eDNEKKu%LL%%ug.	 && 
 ! 	HHQK 	)LLBC !!%( 	KIIEu ##GMM22		H% LL(G HI!!%(II.2II193G3G3IJJ	KsQ   A D= #A!D# D# A	D= #D:7D= 9D::D= = I,7I,	I,!CI''I,c           	         / n[         R                  " UUU R                  U R                  U R                  UU R
                  5      nUR                  U5      nU R                  R                  UR                  R                  5        U$ )zExecute AST parse on each file

:param fname: The name of the file being parsed
:param data: Original file contents
:param lines: The lines of code to process
:return: The accumulated test score
)
b_node_visitorBanditNodeVisitorr   r!   r   r   processr   extendtester)r#   r   r   rB   r   r   ress          r&   r   "BanditManager._execute_ast_visitorZ  so     ..IIIIJJLL
 D!CJJ../r)   )r   r   r   r!   r   r   r   r   r   r   r   r   r"   r   r   )FFFNFr5   )F )__name__
__module____qualname____firstlineno__scoper'   r2   b_constantsLOWr9   rG   r6   rT   rn   r   r   r   r   __static_attributes__ r)   r&   r   r       sy    E &P $KOO:
;4 %koo	A$ 9v;5z&!P+KZr)   r   c                 P   U(       d  S/nU(       d  / n[        5       n[        5       n[        R                  " U 5       Hc  u  pVnU HW  n[        R                  R	                  XX5      n	[        XU5      (       a  UR                  U	5        MF  UR                  U	5        MY     Me     X44$ )Nrs   )r{   re   walkr~   r   r   r   )
	files_dirrv   rw   r   r   rootr   r   filenamer~   s
             r&   r   r   r  s        "JUN''),H77<</D 7LMMt$""4(  - %%r)   c                    ^  Sn[        T U5      (       d  U(       d-  [        T U5      (       d  [        U 4S jU 5       5      (       d  SnU$ )a:  Determine if a file should be included based on filename

This utility function determines if a file should be included based
on the file name, a list of parsed extensions, excluded paths, and a flag
specifying whether extensions should be enforced.

:param path: Full path of file to check
:param parsed_extensions: List of parsed extensions
:param excluded_paths: List of paths (globbing supported) from which we
    should not include files
:param enforce_glob: Can set to false to bypass extension check
:return: Boolean indicating whether a file should be included
Fc              3   ,   >#    U  H	  oT;   v   M     g 7fr5   r   ).0r   r~   s     r&   	<genexpr>$_is_file_included.<locals>.<genexpr>  s      K
4!I4s   T)_matches_glob_listany)r~   rv   rw   rx   return_values   `    r&   r   r     sS      L $//|!$(=>>s K
4K
 H
 H
  Lr)   c                 P    U H   n[         R                   " X5      (       d  M     g   g)NTF)fnmatch)r   	glob_listglobs      r&   r   r     s#    ??8**  r)   c                 @    U Vs/ s H  o"U ;  d  M
  UPM     sn$ s  snf )a*  Compare a baseline list of issues to list of results

This function compares a baseline set of issues to a current set of issues
to find results that weren't present in the baseline.

:param baseline: Baseline list of issues
:param results: Current list of issues
:return: List of unmatched issues
r   )r   r   as      r&   rK   rK     s!     4w!8"3Aw444s   	c                     [         R                  " 5       nU  H  nU Vs/ s H  oCU:X  d  M
  UPM     snX#'   M!     U$ s  snf )a  Returns a dictionary with issue candidates

For example, let's say we find a new command injection issue in a file
which used to have two.  Bandit can't tell which of the command injection
issues in the file are new, so it will show all three.  The user should
be able to pick out the new one.

:param unmatched_issues: List of issues that weren't present before
:param results_list: main list of current Bandit findings
:return: A dictionary with a list of candidates for each issue
)collectionsOrderedDict)unmatched_issuesresults_listissue_candidatesrP   rO   s        r&   rL   rL     sK     #..0%	#'
#!A~A|'
# &
 	'
s   	==c                     U R                  U5      nU(       a  U$ U R                  U5      nU(       d  [        R                  SU5        U$ )Nz6Test in comment: %s is not a test name or id, ignoring)check_idget_test_idr@   rA   )extmanmatchtest_ids      r&   _find_test_id_from_nosec_stringr     sC    ooe$G  'GDe	
 Nr)   c                 z   [         R                  U 5      nU(       d  g UR                  5       nUR                  S[	        5       5      n[	        5       nU(       ab  [
        R                  n[        R                  U5       H9  nUR                  S5      n[        XW5      nU(       d  M(  UR                  U5        M;     U$ )Ntestsr+   )NOSEC_COMMENTsearch	groupdictgetr{   r   r`   NOSEC_COMMENT_TESTSfinditergroupr   r   )	commentfound_no_sec_commentmatchesnosec_teststest_idsr   test
test_matchr   s	            r&   r   r     s    (//8",,.G++gsu-K uH!))'00=DAJ5fIGwW%	 > Or)   )NN)T)(r   r   r   r<   r   re   rerb   r   r   richr   bandit.corer   r   r   r   r   r   r   r	   r   r
   r   	getLoggerr   r@   compiler   
IGNORECASEr  r   r   r   r   r   rK   rL   r   r   r   r)   r&   <module>r     s   
   	   	 	 
    0 (  .  6 .!

?@jj!;R]]K  O Of
 ;?&. ?C:
5.r)   