
    ZiL#                         S r SSKrSSKJr  SSKJrJr   SSKJrJ	r	J
r
Jr  SrS	 rS
 rS rSS jrS rg! \ a    Sr\" S5         N$f = f)uU   
路由层通用工具函数

提供文件操作、题目数据获取等通用功能
    N)Path)jsonifyg)get_latest_challengeget_challenge_by_nameupdate_challengeget_challenge_recordTFuE   数据库操作模块导入失败，将使用文件方式读取数据c                  p    [        [        5      R                  R                  R                  R                  $ )u   获取项目根目录)r   __file__parent     A   /Users/yu22x/Desktop/ddd_副本135/ctf/app/routes/common/utils.pyget_project_rootr      s$    >  ''..555r   c                 r    1 Skn[         R                  R                  U 5      S   R                  5       nX!;   $ )u   
检查文件是否为二进制文件

Args:
    filename: 文件名或文件路径
    
Returns:
    bool: 是否为二进制文件
>   .7z.gz.so.avi.bin.bmp.bz2.dll.eot.exe.gif.ico.jpg.mov.mp3.mp4.otf.pdf.png.rar.svg.tar.ttf.wav.zip.jpeg.woff.dylib.woff2   )ospathsplitextlower)filenamebinary_extensionsexts      r   is_binary_filer7      s7     ''

8
$Q
'
-
-
/C##r   c                 
   U (       d  g SSK JnJn  U   UR                  5        HB  u  p4UR	                  S5      U :X  d  M  UR	                  SS5      nU(       d  M7  Us  sSSS5        $    SSS5        [        (       a7   [        [        U 5      5      nU(       a  UR	                  S5      nU(       a  U$ gg! , (       d  f       NQ= f! [
         a     N`f = f! [         a!  n[        S[        U5       35         SnAgSnAff = f)	u   
通过 challenge_id 从任务记录或数据库获取 category_id

Args:
    challenge_id: 题目ID
    
Returns:
    str: category_id，如果找不到则返回 'web'（默认）
webr   )tasks_status_tasks_lockchallenge_idcategory_idNchallenge_typeu&   从数据库读取题目记录失败: )app.routes.generator.tasksr:   r;   itemsgetImportErrorHAS_DB_OPERATIONSr	   int	Exceptionprintstr)	r<   r:   r;   task_idtaskr=   challenge_datar>   es	            r   get_category_id_from_challengerL   2   s     	H!-!3!3!588N+|;"&((=%"@K"{** [!5  	E1#l2CDN!/!3!34D!E!))
 - [    	E:3q6(CDD 		Es^   
C )B6B6B6	C )B6+C ?4C 6
C C C 
CC
D!C==Dc           	      L   [         (       d  S[        SSS.5      S44$ U (       a  [        [        U 5      5      nO
[	        5       nU(       d  S[        SSS.5      S44$ [        [        S5      (       as  [        R                  (       a^  UR                  S	5      [        R                  R                  :w  a0  [        R                  R                  S
:w  a  S[        SSS.5      S44$ OS[        SSS.5      S44$ UR                  S5      nU(       a  [        U5      OSnX1S'   UR                  S5      n[        5       nU(       d  S[        SSS.5      S44$ UnUR                  S5      (       d1  [        R                  R!                  U5      (       d  [#        XT-  5      n[        R                  R%                  U5      (       d  ['        U5      nUR(                  nUS-  U-  S-  U-  n	U	R%                  5       (       aW  [#        U	R+                  U5      5      n
[#        U	5      n[         (       a%   [-        USU
05        [/        SU SU SU
 35        GOHGOFS[        SSU SU	 S3S.5      S44$ ['        U5      nS[#        UR2                  5      ;   Ga   UR2                  nSn[5        U5       H  u  nnUS:X  d  M  Un  O   Ub  [7        U5      US-   :  a  XS-      S:X  a  US    nUS-  U-  S-  U-  n	U	R%                  5       (       d   S!SKnU	R:                  R=                  S"S"S#9  UR?                  [#        U5      [#        U	5      5        [/        S$U SU	 35        [#        U	R+                  U5      5      n
[         (       a  [-        USU
05        [#        U	5      nXU4$ ! [0         a!  n[/        S[#        U5       35         SnAN*SnAff = f! [0         a!  n[/        S%[#        U5       35         SnANXSnAff = f! [0         a!  n[/        S&[#        U5       35         SnANSnAff = f)'u   
获取题目数据和输出目录的公共函数

Args:
    challenge_id: 题目ID，如果为None则获取最新题目

Returns:
    tuple: (challenge_data, output_dir, category_id) 或 (None, error_response)
Nerroru   数据库操作不可用)statusmessagei  u   未找到题目数据i  useruser_idadminu   您没有权限查看此题目i  u   请先登录i  idr9   r=   
output_diru   输出目录未设置/ge10outputu   已更新题目 u    的 output_dir: z -> u#   更新数据库 output_dir 失败: u   输出目录不存在: u   （已尝试新路径: u   ）   r/   r   T)parentsexist_oku   已迁移题目目录: u   迁移题目目录失败: u   检查旧格式路径失败: ) rC   r   r	   rD   r   hasattrr   rQ   rA   rT   rolerL   r   
startswithr0   r1   isabsrG   existsr   namerelative_tor   rF   rE   parts	enumeratelenshutilr   mkdirmove)r<   rJ   challenge_id_intr=   rU   project_rootoriginal_output_dirold_output_pathchallenge_dir_namenew_output_dirnew_output_dir_strrK   output_pathrd   
ge10_indexipartrg   s                     r   get_challenge_and_output_dirru   [   s@    g=WXY[^___-c,.?@-/g=TUVX[\\\ q&affi(AFFII5!&&++:P'WAa"bcehiii g^LMsSSS &))$/FV01AB\aK %0=!  ##L1J#%Lg=TUVX[\\\ %  %%bggmmJ.G.G23
 77>>*%%23,11 &.<xGJ\\  ""!$^%?%?%M!N^,J ! J$%5FX7YZ,-=,>>OPcOddhi{h|}~ ! '!4ZL@WXfWggjk#     :&S**++!@#))!
(/GAtv~%&
  0
 )c%j:>.I!^,8-22Y*)5)>)Lx)WZl)l  .4466M - . 5 5 ; ;DSW ; X &C,<c.>Q R %(?}DQ_P`&a b 699S9ST`9a5b 2#4#4$45EVhGi$j-0-@
 {22a ! J?AxHIIJT $- M %(B3q6(&K L LM  @5c!fX>??@s\   ,"N #O8 8AO8 BO
 
O&OO

O5O0+O8 0O55O8 8
P#PP#c                      [        U 5      R                  5       n[        U 5      U-  R                  5       nUR                  U5      $ ! [        [        4 a     gf = f)u   
验证文件路径是否在基础目录内（防止路径遍历攻击）

Args:
    base_dir: 基础目录
    file_path: 要验证的文件路径
    
Returns:
    bool: 是否合法
F)r   resolveis_relative_to
ValueErrorOSError)base_dir	file_pathbasetargets       r   validate_file_pathr      sX    H~%%'x.9,557$$T**  s   AA AA)N)__doc__r0   pathlibr   flaskr   r   app.models.database.operationsr   r   r   r	   rC   rB   rF   r   r7   rL   ru   r   r   r   r   <module>r      sl   
 
  
S  6
$*&Ru3pA  S	
QRSs   6 A	A	