Skip to content

Commit c873e4d

Browse files
authored
fix(http): inconsistencies on urlpattern usage on scope (#1059)
* fix(http): inconsistencies on urlpattern usage on scope * fix tests * enhance tests
1 parent 4e37316 commit c873e4d

2 files changed

Lines changed: 64 additions & 7 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"http": patch
3+
---
4+
5+
Fixes scope not allowing subpaths, query parameters and hash when those values are empty.

plugins/http/src/scope.rs

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::sync::Arc;
66

77
use serde::{Deserialize, Deserializer};
88
use url::Url;
9-
use urlpattern::{UrlPattern, UrlPatternInit, UrlPatternMatchInput};
9+
use urlpattern::{UrlPattern, UrlPatternMatchInput};
1010

1111
#[allow(rustdoc::bare_urls)]
1212
#[derive(Debug)]
@@ -15,7 +15,21 @@ pub struct Entry {
1515
}
1616

1717
fn parse_url_pattern(s: &str) -> Result<UrlPattern, urlpattern::quirks::Error> {
18-
let init = UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
18+
let mut init = urlpattern::UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
19+
if init.search.as_ref().map(|p| p.is_empty()).unwrap_or(true) {
20+
init.search.replace("*".to_string());
21+
}
22+
if init.hash.as_ref().map(|p| p.is_empty()).unwrap_or(true) {
23+
init.hash.replace("*".to_string());
24+
}
25+
if init
26+
.pathname
27+
.as_ref()
28+
.map(|p| p.is_empty() || p == "/")
29+
.unwrap_or(true)
30+
{
31+
init.pathname.replace("*".to_string());
32+
}
1933
UrlPattern::parse(init)
2034
}
2135

@@ -100,6 +114,7 @@ mod tests {
100114
let deny = Arc::new("http://localhost:8080/*".parse().unwrap());
101115
let scope = super::Scope::new(vec![&allow], vec![&deny]);
102116
assert!(!scope.is_allowed(&"http://localhost:8080/file.png".parse().unwrap()));
117+
assert!(!scope.is_allowed(&"http://localhost:8080?framework=tauri".parse().unwrap()));
103118
}
104119

105120
#[test]
@@ -109,9 +124,10 @@ mod tests {
109124
let scope = super::Scope::new(vec![&entry], Vec::new());
110125
assert!(scope.is_allowed(&"http://localhost:8080".parse().unwrap()));
111126
assert!(scope.is_allowed(&"http://localhost:8080/".parse().unwrap()));
127+
assert!(scope.is_allowed(&"http://localhost:8080/file".parse().unwrap()));
128+
assert!(scope.is_allowed(&"http://localhost:8080/path/to/asset.png".parse().unwrap()));
129+
assert!(scope.is_allowed(&"http://localhost:8080/path/list?limit=50".parse().unwrap()));
112130

113-
assert!(!scope.is_allowed(&"http://localhost:8080/file".parse().unwrap()));
114-
assert!(!scope.is_allowed(&"http://localhost:8080/path/to/asset.png".parse().unwrap()));
115131
assert!(!scope.is_allowed(&"https://localhost:8080".parse().unwrap()));
116132
assert!(!scope.is_allowed(&"http://localhost:8081".parse().unwrap()));
117133
assert!(!scope.is_allowed(&"http://local:8080".parse().unwrap()));
@@ -124,6 +140,7 @@ mod tests {
124140
let scope = super::Scope::new(vec![&entry], Vec::new());
125141

126142
assert!(scope.is_allowed(&"http://localhost:8080/file.png".parse().unwrap()));
143+
assert!(scope.is_allowed(&"http://localhost:8080/file.png?q=1".parse().unwrap()));
127144

128145
assert!(!scope.is_allowed(&"http://localhost:8080".parse().unwrap()));
129146
assert!(!scope.is_allowed(&"http://localhost:8080/file".parse().unwrap()));
@@ -136,7 +153,13 @@ mod tests {
136153
let scope = super::Scope::new(vec![&entry], Vec::new());
137154

138155
assert!(scope.is_allowed(&"http://localhost:8080/file.png".parse().unwrap()));
156+
assert!(scope.is_allowed(&"http://localhost:8080/file.png#head".parse().unwrap()));
139157
assert!(scope.is_allowed(&"http://localhost:8080/assets/file.png".parse().unwrap()));
158+
assert!(scope.is_allowed(
159+
&"http://localhost:8080/assets/file.png?width=100&height=200"
160+
.parse()
161+
.unwrap()
162+
));
140163

141164
assert!(!scope.is_allowed(&"http://localhost:8080/file.jpeg".parse().unwrap()));
142165
}
@@ -147,7 +170,15 @@ mod tests {
147170
let scope = super::Scope::new(vec![&entry], Vec::new());
148171

149172
assert!(scope.is_allowed(&"http://something.else".parse().unwrap()));
150-
assert!(!scope.is_allowed(&"http://something.else/path/to/file".parse().unwrap()));
173+
assert!(scope.is_allowed(&"http://something.else#tauri".parse().unwrap()));
174+
assert!(scope.is_allowed(&"http://something.else/path/to/file".parse().unwrap()));
175+
assert!(scope.is_allowed(&"http://something.else?rel=tauri".parse().unwrap()));
176+
assert!(scope.is_allowed(
177+
&"http://something.else/path/to/file.mp4?start=500"
178+
.parse()
179+
.unwrap()
180+
));
181+
151182
assert!(!scope.is_allowed(&"https://something.else".parse().unwrap()));
152183

153184
let entry = Arc::new("http://*/*".parse().unwrap());
@@ -163,10 +194,11 @@ mod tests {
163194
let scope = super::Scope::new(vec![&entry], Vec::new());
164195

165196
assert!(scope.is_allowed(&"http://something.else".parse().unwrap()));
166-
assert!(!scope.is_allowed(&"http://something.else/path/to/file".parse().unwrap()));
197+
assert!(scope.is_allowed(&"http://something.else/path/to/file".parse().unwrap()));
167198
assert!(scope.is_allowed(&"file://path".parse().unwrap()));
168-
assert!(!scope.is_allowed(&"file://path/to/file".parse().unwrap()));
199+
assert!(scope.is_allowed(&"file://path/to/file".parse().unwrap()));
169200
assert!(scope.is_allowed(&"https://something.else".parse().unwrap()));
201+
assert!(scope.is_allowed(&"https://something.else?x=1#frag".parse().unwrap()));
170202

171203
let entry = Arc::new("*://*/*".parse().unwrap());
172204
let scope = super::Scope::new(vec![&entry], Vec::new());
@@ -176,4 +208,24 @@ mod tests {
176208
assert!(scope.is_allowed(&"file://path/to/file".parse().unwrap()));
177209
assert!(scope.is_allowed(&"https://something.else".parse().unwrap()));
178210
}
211+
212+
#[test]
213+
fn validate_query() {
214+
let entry = Arc::new("https://tauri.app/path?x=*".parse().unwrap());
215+
let scope = super::Scope::new(vec![&entry], Vec::new());
216+
217+
assert!(scope.is_allowed(&"https://tauri.app/path?x=5".parse().unwrap()));
218+
219+
assert!(!scope.is_allowed(&"https://tauri.app/path?y=5".parse().unwrap()));
220+
}
221+
222+
#[test]
223+
fn validate_hash() {
224+
let entry = Arc::new("https://tauri.app/path#frame*".parse().unwrap());
225+
let scope = super::Scope::new(vec![&entry], Vec::new());
226+
227+
assert!(scope.is_allowed(&"https://tauri.app/path#frame".parse().unwrap()));
228+
229+
assert!(!scope.is_allowed(&"https://tauri.app/path#work".parse().unwrap()));
230+
}
179231
}

0 commit comments

Comments
 (0)