xoofx / zio

A cross-platform abstract/virtual filesystem framework with many built-ins filesystems for .NET
BSD 2-Clause "Simplified" License
806 stars 61 forks source link

SubFileSystem watcher (sometimes) silently discards events #91

Closed Metapyziks closed 4 weeks ago

Metapyziks commented 4 weeks ago

Summary

This is a Windows-specific bug caused by System.IO.Path.GetFullPath calling System.IO.PathHelper.TryExpandShortFileName for paths containing a ~.

Symptoms

IFileSystemWatcher events created from a SubFileSystem will be silently discarded if all these conditions are met:

We noticed this when watching for .cs file changes while editing using Visual Studio. VS won't directly write to files when saving, instead creating a temporary file named something like Example~xxxx.tmp, which is then renamed to replace the actual target file.

Cause

GetFullPath gets called by all the PhysicalFileSystem.Watcher.Remap methods via ConvertPathFromInternalImpl:

https://github.com/xoofx/zio/blob/a4b9faf133e018bb738c1c195b56aa9712b41e90/src/Zio/FileSystems/PhysicalFileSystem.cs#L980

This can change the case of the path - even if it was already rooted - if it contains a ~.

Then, SubFileSystem.Watcher.TryConvertPath checks if paths are contained in its SubPath by calling UPath.IsInDirectory, which is case-sensitive:

https://github.com/xoofx/zio/blob/a4b9faf133e018bb738c1c195b56aa9712b41e90/src/Zio/UPathExtensions.cs#L202

When this fails, the event gets silently discarded.

Reproduction

Here's a test demonstrating this:

https://github.com/Facepunch/zio/blob/073a0201895ab9af996c1b30790fbe3c2ccaa5d0/src/Zio.Tests/FileSystems/TestSubFileSystem.cs#L77-L112

Only one case fails: the one where all the conditions above are met.

image

Related