Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full temporary folder will crash cursor initialization #696

Open
lindexi opened this issue May 16, 2019 · 5 comments

Comments

Projects
3 participants
@lindexi
Copy link
Contributor

commented May 16, 2019

  • .NET Core Version: 3.0 Preview5
  • Windows version: windows 10 1903
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes

Problem description:

The cursor will crash at initialization when the temporary folder full.

Actual behavior:

I set a cursor from a resource and use this code.

var uri = new Uri("pack://application:,,,/Foo.cur");
var resource = Application.GetResourceStream(uri);
Cursor = new Cursor(resource.Stream); 

I can find the cursor will crash at initialization when the temporary folder full.

System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost)
System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)
System.IO.Directory.CreateDirectory(String path)
System.IO.FileHelper.CreateAndOpenTemporaryFile(String& filePath, FileAccess fileAccess, FileOptions fileOptions, String extension, String subFolder)
System.Windows.Input.Cursor.LoadFromStream(Stream cursorStream)
System.Windows.Input.Cursor..ctor(Stream cursorStream, Boolean scaleWithDpi)
System.Windows.Input.Cursor..ctor(Stream cursorStream)
FawlalnejajerelaWhallgemcurkear.MainWindow..ctor()

Expected behavior:

The cursor can be set.

Minimal repro:

Run this code when the temporary folder full.

        var uri = new Uri("pack://application:,,,/Text.cur");
        var resource = Application.GetResourceStream(uri);
        Cursor = new Cursor(resource.Stream);

And the other way is set a can not visit folder as the temp folder. And you can see the code in https://github.com/lindexi/lindexi_gd/tree/8e346e750fe2075e1366a2a098d63af3b50db177/FawlalnejajerelaWhallgemcurkear that I set a folder name as D:\lindexi\不存在文件 that is an unauthorized access folder.

Reason

The Cursor.LegacyLoadFromStream will generate a temporary file based on the memory stream. But the Path.GetTempFileName Method limit the number of the files is 65535 and it will throw IOException when overcount.

The LoadFromStream code in https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Cursor.cs,090cb505b6310a4e

The LegacyLoadFromStream code in https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Cursor.cs,935d59bd1efe76e4,references

Actual LoadFromStream may ignore LegacyLoadFromStream. But FileHelper.CreateAndOpenTemporaryFile will generate the file in WPF folder by default and use Path.GetRandomFileName to create a file without check access. And it also crashes when the temp folder can not write.

solution

  1. Set the Environment Variable to the own folder that can read or write.
    Environment.SetEnvironmentVariable("TEMP", newTempFolder); Environment.SetEnvironmentVariable("TMP", newTempFolder);
    Why set the environment variable is safe? Because all the process can call the Path.GetTempFileName that will throw IOException when the other process uses it to create and do not delete.
  2. Use the public Cursor(string cursorFile) replace public Cursor(Stream cursorStream) that the first will call LoadFromFile and the LoadFromFile will load the file and do not need to copy to temp folder.

Reference

WPF 光标初始化的时候 temp 文件夹满了无法创建

@msftbot msftbot bot added this to Needs Triage in Triage Board May 16, 2019

@walterlv

This comment has been minimized.

Copy link
Contributor

commented May 16, 2019

Another crash case: If the Windows disk is full, the cursor creation will also crash.

If we don't cache the generated Cursor instances, the temp folder will soon be full and cause the exception above.

@lindexi

This comment has been minimized.

Copy link
Contributor Author

commented May 16, 2019

Question: what is Switch.System.Windows.AllowExternalProcessToBlockAccessToTemporaryFiles

@lindexi

This comment has been minimized.

@lindexi

This comment has been minimized.

Copy link
Contributor Author

commented May 16, 2019

@rladuca rladuca added the bug label May 20, 2019

@rladuca rladuca added this to the Future milestone May 20, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.