Skip to content

Commit 2cb4afd

Browse files
committed
add early checking for file and dir permissions (and fmt 🙊)
1 parent 300e368 commit 2cb4afd

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

‎lychee-lib/src/types/input/input.rs‎

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,13 @@ impl Input {
174174
try_stream! {
175175
let source = self.source.clone();
176176

177-
let user_input_error = move |e: ErrorKind| RequestError::UserInputContent(source.clone(), Box::new(e));
178-
let discovered_input_error = |e: ErrorKind| RequestError::GetInputContent(self.source.clone(), Box::new(e));
177+
let user_input_error =
178+
move |e: ErrorKind| RequestError::UserInputContent(source.clone(), Box::new(e));
179+
let discovered_input_error =
180+
|e: ErrorKind| RequestError::GetInputContent(self.source.clone(), Box::new(e));
179181

180-
// Handle simple cases that don't need resolution
182+
// Handle simple cases that don't need resolution, and perform simple
183+
// checks for more complex cases.
181184
match self.source {
182185
InputSource::RemoteUrl(url) => {
183186
match resolver.url_contents(*url).await {
@@ -187,8 +190,27 @@ impl Input {
187190
}
188191
return;
189192
}
193+
InputSource::FsPath(ref path) => {
194+
let is_readable = std::fs::metadata(path).and_then(|meta| {
195+
if meta.is_dir() {
196+
std::fs::read_dir(path).map(|_| ())
197+
} else {
198+
std::fs::File::open(path).map(|_| ())
199+
}
200+
});
201+
202+
match is_readable {
203+
Ok(_) => (),
204+
Err(e) => Err(user_input_error(ErrorKind::ReadFileInput(
205+
e,
206+
path.to_path_buf(),
207+
)))?,
208+
}
209+
}
190210
InputSource::Stdin => {
191-
yield Self::stdin_content(self.file_type_hint).await.map_err(user_input_error)?;
211+
yield Self::stdin_content(self.file_type_hint)
212+
.await
213+
.map_err(user_input_error)?;
192214
return;
193215
}
194216
InputSource::String(ref s) => {
@@ -213,35 +235,37 @@ impl Input {
213235
match source_result {
214236
Ok(source) => {
215237
let content_result = match source {
216-
ResolvedInputSource::FsPath(path) => {
217-
Self::path_content(&path).await
218-
},
238+
ResolvedInputSource::FsPath(path) => Self::path_content(&path).await,
219239
ResolvedInputSource::RemoteUrl(url) => {
220240
resolver.url_contents(*url).await
221-
},
241+
}
222242
ResolvedInputSource::Stdin => {
223243
Self::stdin_content(self.file_type_hint).await
224-
},
244+
}
225245
ResolvedInputSource::String(s) => {
226246
Ok(Self::string_content(&s, self.file_type_hint))
227-
},
247+
}
228248
};
229249

230250
match content_result {
231251
Err(_) if skip_missing => (),
232-
Err(e) if matches!(&e, ErrorKind::ReadFileInput(io_err, _) if io_err.kind() == std::io::ErrorKind::InvalidData) => {
252+
Err(e) if matches!(&e, ErrorKind::ReadFileInput(io_err, _) if io_err.kind() == std::io::ErrorKind::InvalidData) =>
253+
{
233254
// If the file contains invalid UTF-8 (e.g. binary), we skip it
234255
if let ErrorKind::ReadFileInput(_, path) = &e {
235-
log::warn!("Skipping file with invalid UTF-8 content: {}", path.display());
256+
log::warn!(
257+
"Skipping file with invalid UTF-8 content: {}",
258+
path.display()
259+
);
236260
}
237-
},
261+
}
238262
Err(e) => Err(discovered_input_error(e))?,
239263
Ok(content) => {
240264
sources_empty = false;
241265
yield content
242266
}
243267
}
244-
},
268+
}
245269
Err(e) => Err(discovered_input_error(e))?,
246270
}
247271
}

0 commit comments

Comments
 (0)