From 545a4a50990a63e70c3147c5e35a9104bde45c6c Mon Sep 17 00:00:00 2001 From: monojenkins Date: Thu, 8 Aug 2019 19:08:01 -0400 Subject: [PATCH] =?UTF-8?q?[mono-2019-02]=20Guard=20against=20attempting?= =?UTF-8?q?=20to=20creating=20out-of-range=20spans=20in=20macOS=20File?= =?UTF-8?q?=E2=80=A6=20(#322)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Guard against attempting to creating out-of-range spans in macOS FileSystemWatcher * Only slice out the root watch directory from path iff it is actually the first part of the path Backport of #317. --- .../src/System/IO/FileSystemWatcher.OSX.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs b/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs index a42e637ca3f3..cd124256af9d 100644 --- a/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs +++ b/src/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs @@ -435,7 +435,9 @@ private unsafe void ProcessEvents(int numEvents, // The base FileSystemWatcher does a match check against the relative path before combining with // the root dir; however, null is special cased to signify the root dir, so check if we should use that. ReadOnlySpan relativePath = ReadOnlySpan.Empty; - if (!path.Equals(_fullDirectory, StringComparison.OrdinalIgnoreCase)) + if (!path.Equals(_fullDirectory, StringComparison.OrdinalIgnoreCase) + && path.Length >= _fullDirectory.Length + && _fullDirectory.AsSpan().Equals(path.Slice(_fullDirectory.Length), StringComparison.OrdinalIgnoreCase)) { // Remove the root directory to get the relative path relativePath = path.Slice(_fullDirectory.Length); @@ -479,9 +481,18 @@ private unsafe void ProcessEvents(int numEvents, else { // Remove the base directory prefix and add the paired event to the list of - // events to skip and notify the user of the rename - ReadOnlySpan newPathRelativeName = events[pairedId].Span.Slice(_fullDirectory.Length); - watcher.NotifyRenameEventArgs(WatcherChangeTypes.Renamed, newPathRelativeName, relativePath); + // events to skip and notify the user of the rename + if (events[pairedId].Span.Length >= _fullDirectory.Length + && ((ReadOnlySpan) events[pairedId].Span).Equals(_fullDirectory.AsSpan(0, events[pairedId].Span.Length), StringComparison.OrdinalIgnoreCase)) + { + ReadOnlySpan newPathRelativeName = events[pairedId].Span.Slice(_fullDirectory.Length); + watcher.NotifyRenameEventArgs(WatcherChangeTypes.Renamed, newPathRelativeName, relativePath); + } + else + { + //if the base directory prefix isn't there, just use the full absolute path + watcher.NotifyRenameEventArgs(WatcherChangeTypes.Renamed, events[pairedId].Span, relativePath); + } // Create a new list, if necessary, and add the event if (handledRenameEvents == null)