Skip to content

Commit 539bc95

Browse files
riberkJohnTitor
andauthored
FIX: FsEventWatcher crashes when dealing with empty path (#718)
Co-authored-by: Yuki Okushi <[email protected]>
1 parent a256610 commit 539bc95

File tree

2 files changed

+68
-24
lines changed

2 files changed

+68
-24
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
- CHANGE: raise MSRV to 1.82 **breaking**
55

6+
## notify (unreleased)
7+
- FIX: Fix the bug that `FsEventWatcher` crashes when dealing with empty path [#718]
8+
9+
[#718]: https://github.com/notify-rs/notify/pull/718
10+
11+
612
## notify 8.2.0 (2025-08-03)
713
- FEATURE: notify user if inotify's `max_user_watches` has been reached [#698]
814
- FIX: `INotifyWatcher` ignore events with unknown watch descriptors (instead of `EventMask::Q_OVERFLOW`) [#700]

notify/src/fsevent.rs

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,9 @@ impl FsEventWatcher {
353353
let mut err: cf::CFErrorRef = ptr::null_mut();
354354
let cf_path = cf::str_path_to_cfstring_ref(str_path, &mut err);
355355
if cf_path.is_null() {
356-
cf::CFRelease(err as cf::CFRef);
356+
if !err.is_null() {
357+
cf::CFRelease(err as cf::CFRef);
358+
}
357359
return Err(Error::watch_not_found().add_path(path.into()));
358360
}
359361

@@ -614,38 +616,74 @@ impl Drop for FsEventWatcher {
614616
}
615617
}
616618

617-
#[test]
618-
fn test_fsevent_watcher_drop() {
619+
#[cfg(test)]
620+
mod tests {
621+
use crate::ErrorKind;
622+
619623
use super::*;
620-
use std::time::Duration;
621624

622-
let dir = tempfile::tempdir().unwrap();
625+
#[test]
626+
fn test_fsevent_watcher_drop() {
627+
use super::*;
628+
use std::time::Duration;
629+
630+
let dir = tempfile::tempdir().unwrap();
623631

624-
let (tx, rx) = std::sync::mpsc::channel();
632+
let (tx, rx) = std::sync::mpsc::channel();
625633

626-
{
627-
let mut watcher = FsEventWatcher::new(tx, Default::default()).unwrap();
628-
watcher.watch(dir.path(), RecursiveMode::Recursive).unwrap();
629-
thread::sleep(Duration::from_millis(2000));
630-
println!("is running -> {}", watcher.is_running());
634+
{
635+
let mut watcher = FsEventWatcher::new(tx, Default::default()).unwrap();
636+
watcher.watch(dir.path(), RecursiveMode::Recursive).unwrap();
637+
thread::sleep(Duration::from_millis(2000));
638+
println!("is running -> {}", watcher.is_running());
639+
640+
thread::sleep(Duration::from_millis(1000));
641+
watcher.unwatch(dir.path()).unwrap();
642+
println!("is running -> {}", watcher.is_running());
643+
}
631644

632645
thread::sleep(Duration::from_millis(1000));
633-
watcher.unwatch(dir.path()).unwrap();
634-
println!("is running -> {}", watcher.is_running());
635-
}
636646

637-
thread::sleep(Duration::from_millis(1000));
647+
for res in rx {
648+
let e = res.unwrap();
649+
println!("debug => {:?} {:?}", e.kind, e.paths);
650+
}
638651

639-
for res in rx {
640-
let e = res.unwrap();
641-
println!("debug => {:?} {:?}", e.kind, e.paths);
652+
println!("in test: {} works", file!());
642653
}
643654

644-
println!("in test: {} works", file!());
645-
}
655+
#[test]
656+
fn test_steam_context_info_send_and_sync() {
657+
fn check_send<T: Send + Sync>() {}
658+
check_send::<StreamContextInfo>();
659+
}
646660

647-
#[test]
648-
fn test_steam_context_info_send_and_sync() {
649-
fn check_send<T: Send + Sync>() {}
650-
check_send::<StreamContextInfo>();
661+
#[test]
662+
fn does_not_crash_with_empty_path() {
663+
let mut watcher = FsEventWatcher::new(|_| {}, Default::default()).unwrap();
664+
665+
let watch_result = watcher.watch(Path::new(""), RecursiveMode::Recursive);
666+
assert!(
667+
matches!(
668+
watch_result,
669+
Err(Error {
670+
kind: ErrorKind::PathNotFound,
671+
paths: _
672+
})
673+
),
674+
"actual: {watch_result:#?}"
675+
);
676+
677+
let unwatch_result = watcher.unwatch(Path::new(""));
678+
assert!(
679+
matches!(
680+
unwatch_result,
681+
Err(Error {
682+
kind: ErrorKind::WatchNotFound,
683+
paths: _
684+
})
685+
),
686+
"actual: {unwatch_result:#?}"
687+
);
688+
}
651689
}

0 commit comments

Comments
 (0)