
    xi                         % S r SSKrSSKJr  SSKJr  S\S\4S jr\" \R                  " 5       5      q	\\
S'   S	\SS4S
 jrS\4S jrSS.S\S\\   S\4S jjrSS\S\4S jjrg)u  Path sanitisation helpers for training modules.

Provides a single ``safe_path`` function that validates user-provided
filesystem paths against a known safe root directory.  The validation
uses ``os.path.realpath`` followed by a ``.startswith`` check — the
exact pattern that CodeQL recognises as a sanitiser for the
``py/path-injection`` query.

Symlinks are resolved on both the root and user paths so that paths
through symlinks (e.g. ``/root/data`` → ``/vepfs/.../data``) are
compared consistently.

All training modules that accept user-supplied paths should call
``safe_path`` (or ``safe_open``) before performing any filesystem I/O.
    N)Optional)loggerpathreturnc                 z    [         R                  R                  [         R                  R                  U 5      5      $ )zNormalise and resolve symlinks in *path*.

Uses ``os.path.realpath`` so that symlinked prefixes are resolved
to their canonical form before comparison.
)osr   normpathrealpath)r   s    S/mnt/workspace/acestep.cpp/tests/../../ACE-Step-1.5/acestep/training/path_safety.py_resolver      s(     77BGG,,T233    
_SAFE_ROOTrootc                     [        U 5      qg)zlOverride the safe root directory.

Args:
    root: New safe root (will be normalised and symlink-resolved).
N)r   r   )r   s    r   set_safe_rootr   &   s     $Jr   c                      [         $ )z'Return the current safe root directory.)r    r   r   get_safe_rootr   0   s    r   )base	user_pathr   c          	      h   Ub  [        U5      nO[        n[        R                  R	                  U 5      (       a  [        U 5      nO([        [        R                  R                  X 5      5      nUR                  U[        R                  -   5      (       d  X2:w  a  [        SU < SU< SU< S35      eU$ )aj  Validate and normalise a user-provided path.

The returned path is guaranteed to live under *base* (or the
global ``_SAFE_ROOT`` when *base* is ``None``).  Symlinks in both
the root and user path are resolved so that paths through symlinks
compare correctly.

Args:
    user_path: Untrusted path string from user input.
    base: Optional explicit base directory.  When provided it is
          resolved (symlinks included) and used instead of
          ``_SAFE_ROOT``.

Returns:
    Normalised, symlink-resolved absolute path within the safe root.

Raises:
    ValueError: If the resolved path escapes the safe root.
zPath escapes safe root: z (resolved to z, root=))	r   r   r   r   isabsjoin
startswithsep
ValueError)r   r   r   
normaliseds       r   	safe_pathr   5   s    ( ~ 
ww}}Yi(
bggll4;<

   //J4F&ym 4&>;
 	

 r   modec                 0    [        U 5      n[        X140 UD6$ )a8  Open a file after validating its path.

Convenience wrapper around ``safe_path`` + ``open``.

Args:
    user_path: Untrusted path string.
    mode: File open mode.
    **kwargs: Extra keyword arguments forwarded to ``open``.

Returns:
    File object.

Raises:
    ValueError: If the path escapes the safe root.
)r   open)r   r    kwargs	validateds       r   	safe_openr%   `   s      )$I	*6**r   )r)__doc__r   typingr   logurur   strr   getcwdr   __annotations__r   r   r   r%   r   r   r   <module>r-      s     
  43 43 4 299;'
C '     s 
 8< ( (x} ( (V+ +C +r   