11import inspect
22import logging
33import os
4+ import sys
45
56from collections import Counter
67from pathlib import Path
78from time import gmtime , strftime
89
910import pytest
1011
11- from sanic import text
12+ from sanic import Sanic , text
1213from sanic .exceptions import FileNotFound
1314
1415
@@ -21,6 +22,22 @@ def static_file_directory():
2122 return static_directory
2223
2324
25+ @pytest .fixture (scope = "module" )
26+ def double_dotted_directory_file (static_file_directory : str ):
27+ """Generate double dotted directory and its files"""
28+ if sys .platform == "win32" :
29+ raise Exception ("Windows doesn't support double dotted directories" )
30+
31+ file_path = Path (static_file_directory ) / "dotted.." / "dot.txt"
32+ double_dotted_dir = file_path .parent
33+ Path .mkdir (double_dotted_dir , exist_ok = True )
34+ with open (file_path , "w" ) as f :
35+ f .write ("DOT\n " )
36+ yield file_path
37+ Path .unlink (file_path )
38+ Path .rmdir (double_dotted_dir )
39+
40+
2441def get_file_path (static_file_directory , file_name ):
2542 return os .path .join (static_file_directory , file_name )
2643
@@ -578,3 +595,40 @@ def test_resource_type_dir(app, static_file_directory):
578595def test_resource_type_unknown (app , static_file_directory , caplog ):
579596 with pytest .raises (ValueError ):
580597 app .static ("/static" , static_file_directory , resource_type = "unknown" )
598+
599+
600+ @pytest .mark .skipif (
601+ sys .platform == "win32" ,
602+ reason = "Windows does not support double dotted directories" ,
603+ )
604+ def test_dotted_dir_ok (
605+ app : Sanic , static_file_directory : str , double_dotted_directory_file : Path
606+ ):
607+ app .static ("/foo" , static_file_directory )
608+ double_dotted_directory_file = str (double_dotted_directory_file ).lstrip (
609+ static_file_directory
610+ )
611+ _ , response = app .test_client .get ("/foo/" + double_dotted_directory_file )
612+ assert response .status == 200
613+ assert response .body == b"DOT\n "
614+
615+
616+ def test_breakout (app : Sanic , static_file_directory : str ):
617+ app .static ("/foo" , static_file_directory )
618+
619+ _ , response = app .test_client .get ("/foo/..%2Fstatic/test.file" )
620+ assert response .status == 400
621+
622+
623+ @pytest .mark .skipif (
624+ sys .platform != "win32" , reason = "Block backslash on Windows only"
625+ )
626+ def test_double_backslash_prohibited_on_win32 (
627+ app : Sanic , static_file_directory : str
628+ ):
629+ app .static ("/foo" , static_file_directory )
630+
631+ _ , response = app .test_client .get ("/foo/static/..\\ static/test.file" )
632+ assert response .status == 400
633+ _ , response = app .test_client .get ("/foo/static\\ ../static/test.file" )
634+ assert response .status == 400
0 commit comments