@@ -53,3 +53,107 @@ def test_Loader_initialisation_with_neither_TMP_HOME_set(tmp_dir_fixture):
53
53
54
54
loader = Loader (ctx = {})
55
55
assert isinstance (loader .session , Session )
56
+
57
+ def test_DefaultFetcher_urljoin_win32 (tmp_dir_fixture ):
58
+ import os
59
+ import sys
60
+ from schema_salad .ref_resolver import DefaultFetcher
61
+ from requests import Session
62
+
63
+ # Ensure HOME is set.
64
+ os .environ ["HOME" ] = tmp_dir_fixture
65
+
66
+ actual_platform = sys .platform
67
+ try :
68
+ # For this test always pretend we're on Windows
69
+ sys .platform = "win32"
70
+ fetcher = DefaultFetcher ({}, None )
71
+ # Relative path, same folder
72
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "soup.cwl" )
73
+ assert url == "file:///C:/Users/fred/soup.cwl"
74
+ # Relative path, sub folder
75
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "foo/soup.cwl" )
76
+ assert url == "file:///C:/Users/fred/foo/soup.cwl"
77
+ # relative climb-up path
78
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "../alice/soup.cwl" )
79
+ assert url == "file:///C:/Users/alice/soup.cwl"
80
+
81
+ # Path with drive: should not be treated as relative to directory
82
+ # Note: \ would already have been converted to / by resolve_ref()
83
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "c:/bar/soup.cwl" )
84
+ assert url == "file:///c:/bar/soup.cwl"
85
+ # /C:/ (regular URI absolute path)
86
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "/c:/bar/soup.cwl" )
87
+ assert url == "file:///c:/bar/soup.cwl"
88
+ # Relative, change drive
89
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "D:/baz/soup.cwl" )
90
+ assert url == "file:///d:/baz/soup.cwl"
91
+ # Relative from root of base's D: drive
92
+ url = fetcher .urljoin ("file:///d:/baz/soup.cwl" , "/foo/soup.cwl" )
93
+ assert url == "file:///d:/foo/soup.cwl"
94
+
95
+ # resolving absolute non-drive URIs still works
96
+ url = fetcher .urljoin ("file:///C:/Users/fred/foo.cwl" , "http://example.com/bar/soup.cwl" )
97
+ assert url == "http://example.com/bar/soup.cwl"
98
+ # and of course relative paths from http://
99
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "soup.cwl" )
100
+ assert url == "http://example.com/fred/soup.cwl"
101
+
102
+ # Stay on http:// and same host
103
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "/bar/soup.cwl" )
104
+ assert url == "http://example.com/bar/soup.cwl"
105
+
106
+
107
+ # Security concern - can't resolve file: from http:
108
+ with pytest .raises (ValueError ):
109
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "file:///c:/bar/soup.cwl" )
110
+ # Drive-relative -- should NOT return "absolute" URI c:/bar/soup.cwl"
111
+ # as that is a potential remote exploit
112
+ with pytest .raises (ValueError ):
113
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "c:/bar/soup.cwl" )
114
+
115
+ finally :
116
+ sys .platform = actual_platform
117
+
118
+ def test_DefaultFetcher_urljoin_linux (tmp_dir_fixture ):
119
+ import os
120
+ import sys
121
+ from schema_salad .ref_resolver import DefaultFetcher
122
+ from requests import Session
123
+
124
+ # Ensure HOME is set.
125
+ os .environ ["HOME" ] = tmp_dir_fixture
126
+
127
+ actual_platform = sys .platform
128
+ try :
129
+ # Pretend it's Linux (e.g. not win32)
130
+ sys .platform = "linux2"
131
+ fetcher = DefaultFetcher ({}, None )
132
+ url = fetcher .urljoin ("file:///home/fred/foo.cwl" , "soup.cwl" )
133
+ assert url == "file:///home/fred/soup.cwl"
134
+
135
+ url = fetcher .urljoin ("file:///home/fred/foo.cwl" , "../alice/soup.cwl" )
136
+ assert url == "file:///home/alice/soup.cwl"
137
+ # relative from root
138
+ url = fetcher .urljoin ("file:///home/fred/foo.cwl" , "/baz/soup.cwl" )
139
+ assert url == "file:///baz/soup.cwl"
140
+
141
+ url = fetcher .urljoin ("file:///home/fred/foo.cwl" , "http://example.com/bar/soup.cwl" )
142
+ assert url == "http://example.com/bar/soup.cwl"
143
+
144
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "soup.cwl" )
145
+ assert url == "http://example.com/fred/soup.cwl"
146
+
147
+ # Root-relative -- here relative to http host, not file:///
148
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "/bar/soup.cwl" )
149
+ assert url == "http://example.com/bar/soup.cwl"
150
+
151
+ # Security concern - can't resolve file: from http:
152
+ with pytest .raises (ValueError ):
153
+ url = fetcher .urljoin ("http://example.com/fred/foo.cwl" , "file:///bar/soup.cwl" )
154
+
155
+ # But this one is not "dangerous" on Linux
156
+ fetcher .urljoin ("http://example.com/fred/foo.cwl" , "c:/bar/soup.cwl" )
157
+
158
+ finally :
159
+ sys .platform = actual_platform
0 commit comments