Jump to content

Error Message/Handler ~ needs to show invalid path


Recommended Posts

Hello,

 

I'm creating a custom uri to launch pdn files from a web browser (chrome), but when I do I receive the following error message:

 

Application version: paint.net 4.2.10

System.NotSupportedException: The given path's format is not supported.
   at System.Security.Permissions.FileIOPermission.EmulateFileIOPermissionChecks(String fullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
   at PaintDotNet.Controls.DocumentWorkspace.LoadDocument(Control owner, String fileName, FileType& fileTypeResult, ProgressEventHandler progressCallback) in D:\src\pdn\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 2996

 

... this is probably as simple as altering the encoding/passing of the URI file name parameter; but I can't tell because the error message isn't telling me the path it "received"...

 

In order for you to replicate the issue, on a Windows machine, pls save the following as [ add_pdn_uri.reg ] ...

 

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\pdn]
@="URL:paint dot net link"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\pdn\DefaultIcon]
@="\"C:\\Program Files\\paint.net\\PaintDotNet.exe\",1"

[HKEY_CLASSES_ROOT\pdn\shell]
@="open"

[HKEY_CLASSES_ROOT\pdn\shell\open]
"FriendlyAppName"="PaintDotNet"

[HKEY_CLASSES_ROOT\pdn\shell\open\command]
@="\"C:\\Program Files\\paint.net\\PaintDotNet.exe\" \"%1\""

... and then right click & "merge" the file into the registry (a reboot is not required.)

 

Here are some of the URI's I tried:

pdn:///C:\!Geo\Galaxy_CaelSpiral.pdn
pdn:///Galaxy_CaelSpiral.pdn
pdn:///C%3A%5C%21Geo%5CGalaxy_CaelSpiral.pdn
pdn:///%21Geo%2FGalaxy_CaelSpiral.pdn

... they all give the same error above.


Not that I think you'll need it, as the error above doesn't cause the system to crash & will probably occur regardless of system parameters and/or versioning, but for completeness sake (& also I hate when ppl file bug reports and don't give enough <all> the info) here's my Paint.Net diagnostics info:

Application	paint.net 4.2.10 (Final 4.210.7348.40816)
Build Date	Thursday, February 13, 2020
Install type	Classic
	
Hardware accelerated rendering (GPU)	True
Animations	True
DPI	96 (1.00x scale)
Language	en-US
	
OS	Windows 10 Pro x64 (10.0.18363.0) (0x30)
.NET Runtime	4.0.30319.42000
Physical Memory	24,514 MB
	
CPU	Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
    Speed	~3408 MHz
    Cores / Threads	4 / 8
    Features	SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, AVX, AVX2
	
Video Card	NVIDIA GeForce GT 730
    Dedicated Video RAM	2,007 MB
    Dedicated System RAM	0 MB
    Shared System RAM	12,257 MB
    Vendor ID	0x10DE
    Device ID	0x1287
    Subsystem ID	0x10831028
    Revision	161
    LUID	0x0000D826
    Flags	AcgCompatible, SupportMonitoredFences, KeyedMutexConformance
    Graphics Preemption	DmaBufferBoundary
    Compute Preemption	DmaBufferBoundary
    Outputs	2
    Feature Level	Direct3D_11_0
    DXGI Formats	A8_UNorm, B8G8R8A8_UNorm, R16G16B16A16_UNorm, R16G16B16A16_Float, R32G32B32A32_Float
    Buffer Precision	UNorm8bpc, UNorm8bpcSrgb, UNorm16bpc, Float16bpc, Float32bpc
	
Video Card	Microsoft Basic Render Driver
    Dedicated Video RAM	0 MB
    Dedicated System RAM	0 MB
    Shared System RAM	12,257 MB
    Vendor ID	0x1414
    Device ID	0x008C
    Subsystem ID	0x00000000
    Revision	0
    LUID	0x0000E262
    Flags	Software, AcgCompatible, SupportMonitoredFences, KeyedMutexConformance
    Graphics Preemption	InstructionBoundary
    Compute Preemption	InstructionBoundary
    Outputs	0
    Feature Level	Direct3D_12_1
    DXGI Formats	A8_UNorm, B8G8R8A8_UNorm, R16G16B16A16_UNorm, R16G16B16A16_Float, R32G32B32A32_Float
    Buffer Precision	UNorm8bpc, UNorm8bpcSrgb, UNorm16bpc, Float16bpc, Float32bpc

 

Thank you very much & stay safe !  🙂

Edited by GeorgeHope
Skipped minor step in replication setup.
Link to post
Share on other sites

I was creating my own protocol, because I didn't know there was a built-in paintdotnet: protocol (ironically, I did check for a pdn: protocol, but I didn't think that you would write it out...  😊

 

@Rick Brewster ... I just tried as you suggested, and with a little bit of trial & error (since I didn't have the passed path in the error messages <as described above>), I discovered the following format would work:

  • paintdotnet:C:/!Geo/Galaxy_CaelSpiral.pdn
  • paintdotnet:D:/!Geo/Galaxy_StarValleyReach.pdn

... that being said, the programmer in me then decided to test the following:

  • paintdotnet:D:/!Geo/Test Me Spaces/Galaxy_ValdayDrift.pdn

... and it's somewhat predictable error was:

Application version: paint.net 4.2.10

System.IO.DirectoryNotFoundException: Could not find a part of the path 'D:\!Geo\Test%20Me%20Spaces\Galaxy_ValdayDrift.pdn'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
   at PaintDotNet.Controls.DocumentWorkspace.LoadDocument(Control owner, String fileName, FileType& fileTypeResult, ProgressEventHandler progressCallback) in D:\src\pdn\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 2996

 

... ironically, for some reason, here it bubbles up the passed in path ... 😔

 

I know it's not going to be a high priority; but perhaps the following should be added to the (probably somewhat insurmountable neverending) todo list for the project.. 🙂

 

  • bubble up the path passed into the open call for error messages
  • handle url encoded path parameters (that would handle spaces)
    • ... and probably handle unix vs windows pathing problems:
      • paintdotnet:C:\!Geo\Galaxy_CaelSpiral.pdn
      • System.IO.FileNotFoundException: Could not find file 'C:\Program Files\paint.net\%5C!Geo%5CGalaxy_CaelSpiral.pdn'.
        File name: 'C:\Program Files\paint.net\%5C!Geo%5CGalaxy_CaelSpiral.pdn'

        C#   ~   public static readonly char DirectorySeparatorChar;

In any event, I can work around the items above; and I really appreciate you taking the time to respond!!!  Thank you very much! 😀

 

Please stay safe during the pandemic, & take care.

 

George 2.0

Link to post
Share on other sites

^ this. If the path or filename has spaces in it you need to wrap it in quotes. See https://www.getpaint.net/doc/latest/paintdotnetProtocol.html#3

 

(snigger - Rick Astley. No one seems to have noticed yet....)

Link to post
Share on other sites

Use quotes. I'm not doing the other suggestions because ... use quotes. % is a valid file name character, it wouldn't be good to second guess that, it could end up being a security vulnerability. And / should already be normalized, and even if it weren't ... this is Windows. When in Rome.

  • Like 1

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to post
Share on other sites
Posted (edited)

@Ego Eram Reputo ... I looked at your link, and I don't believe it directly relates ...

<html>
    <body>
        <!-- This works ... -->
        <p><a href="paintdotnet:C:/!Geo/Galaxy_CaelSpiral.pdn">Protocol PaintDotNet</a></p>
        <!-- This does not work ... -->
        <p><a href='paintdotnet:"D:/!Geo/Test Me Spaces/Galaxy_ValdayDrift.pdn"''>Protocol PaintDotNet w Spaces</a></p>
        <!--
            When passed to the Paint.Net program, Paint.Net is receiving the following as an argument:

                paintdotnet:%22D:/!Geo/KickStarter/CyberKnights/Adventure-02/Test%20Me

            ... which I believe Paint.Net does not understand.
        -->
    </body>
</html>

... as it primarily addresses the issue from a batch file perspective; which is not my primary use case.

  • I'm using it to link/open images in Paint.Net from a webpage.

@Rick Brewster I understand what you're saying; however, with the above web page code I believe all of my suggestions are relevant.  In summary, Paint.Net does not properly deal with url encoded arguments, address system agnostic pathing afaik, and does not consistently give useful information when reporting the error in order to troubleshoot the issue...  as this is the error I receive with the above example:

image.png.16cff2de8df2d0f9627f9c39eecff04f.png

Edited by GeorgeHope
Minor Clarification of Issue
Link to post
Share on other sites

@Rick Brewster I would greatly appreciate it if you would take the time to look at my reply:

... the biggest discrepancy, is that in my original post & subsequent documentation, my use case is "<using a> custom uri to launch pdn files from a web browser (chrome)"

 

The protocol you suggest, and in the link (paintdotnet: protocol) provided by @Ego Eram Reputo was designed to be "used to launch the app with command-line parameters" ... but I'm not launching from the command line.  Web pages and web links don't permit un-encoded spaces and/or quotes (" " or ' ') surrounding the passed arguments.

 

This as well as providing either inaccurate (as in the screenshot) or incomplete information (previous posts) in the error messages.

 

Thank you & stay safe.

Link to post
Share on other sites
5 hours ago, GeorgeHope said:

This as well as providing either inaccurate (as in the screenshot) or incomplete information (previous posts) in the error messages.

 

Those error messages are provided by the .NET Framework, Paint.NET does not have any control over them.

 

5 hours ago, GeorgeHope said:

The protocol you suggest, and in the link (paintdotnet: protocol) provided by @Ego Eram Reputo was designed to be "used to launch the app with command-line parameters" ... but I'm not launching from the command line.  Web pages and web links don't permit un-encoded spaces and/or quotes (" " or ' ') surrounding the passed arguments.

 

It sounds like your pdn: protocol should use a helper application that calls Paint.NET instead of trying to call Paint.NET directly.

The helper application could take the URI-encoded path and download it to a temp directory, then you could use the paintdotnet: protocol to open the downloaded file and delete it when Paint.NET is closed.

 

Rick already mentioned that there could be security issues with detecting URI encoded paths.

On 4/18/2020 at 10:47 PM, Rick Brewster said:

Use quotes. I'm not doing the other suggestions because ... use quotes. % is a valid file name character, it wouldn't be good to second guess that, it could end up being a security vulnerability. And / should already be normalized, and even if it weren't ... this is Windows. When in Rome.

 

Why are you trying to open Paint.NET files from a web browser?

PdnSig.png

Plugin Pack | PSFilterPdn | Content Aware Fill | G'MICPaint Shop Pro Filetype | RAW Filetype | WebP Filetype

The small increase in performance you get coding in C++ over C# is hardly enough to offset the headache of coding in the C++ language. ~BoltBait

 

Link to post
Share on other sites
Posted (edited)
6 hours ago, null54 said:

 

Those error messages are provided by the .NET Framework, Paint.NET does not have any control over them.

 

They're only "provided", because the errors are not currently handled properly within the application.  Arguably, I should never receive an unhandled error.

 

Quote

 

It sounds like your pdn: protocol should use a helper application that calls Paint.NET instead of trying to call Paint.NET directly.

The helper application could take the URI-encoded path and download it to a temp directory, then you could use the paintdotnet: protocol to open the downloaded file and delete it when Paint.NET is closed.

 

This isn't constructive...  yes I could do a hundred other things... also, I've already given up on the idea of a custom (my own) [pdn:protocol], there's no point based on how Paint.Net currently parses the first argument anyway... and if @Rick Brewster decides that his [paintdotnet:protocol] is going to be only 'command-line', then it is what it is, it's his software.  I move on, and either work around the existing limitations of the current protocol; or avoid Paint.Net completely.  But it won't be because of a misunderstood use case (which is not command line.)  It also doesn't change that the errors aren't handled properly.

 

Quote

Rick already mentioned that there could be security issues with detecting URI encoded paths.

 

As an experienced enterprise developer, I don't agree with the significance of this statement...  if you're going to accept an argument, you need to validate the argument...  does not allowing URI encoded paths reduce the attack surface, sure...  but I highly doubt with all the emphasis in .Net of web technologies that it cannot safely handle URI encoded paths.

 

Quote

Why are you trying to open Paint.NET files from a web browser?

 

Not that this question really matters... but I want to distribute a utility for a game, web browsers are already installed on Windows, and it reduces my workload.  If Paint.Net were open source, I'd probably have already committed a PR (but for many valid reasons Rick has closed the source.) 

 

Since it is not, my only alternative is to:

  • lay out my case
  • make sure my case is understood
  • & wait for a decision from Rick

 

Though I would normally not add a comment like this for a bug fix / so type question; I want to express my gratitude and thanks for @Rick Brewster for all the hard work he has put into Paint.Net, it clearly shows.  So regardless of his final decisions on the aforementioned issues/requests; I am very appreciative of the software he's released in it's current form.  I also understand, that even if he decides to address the items, it is probably not the highest on the priority list.  My hope is that it's a piece of low hanging fruit, which could be easily resolved.  Thank you @Rick Brewster 🙂

Edited by GeorgeHope
Added commentary on intent.
  • Like 1
Link to post
Share on other sites

I'm not worried about the security of your scenario (although I'm not sure I fully understand all of it), since it seems to all be done on the local system. But, what if a web page linked to a PDN file that had some maliciously crafted image file which took advantage of a bug in a codec that resulted in elevation of privilege? It's possible, it can happen, it has happened (AFAIK). Image codecs are a known bug farm, and probably always will be. They're like wet markets for this stuff. The point being, it's just crucial to be EXTREMELY careful here.

 

The problem with unescaping the %XY stuff is that first the app has to try to open the image without any unescaping. Then, if that fails, it needs to unescape and then try loading again. That's actually a pretty big change to the flow of how all that code works. And that's code which has not changed much in a long time, partly because it really hasn't needed to: it works!

 

The security issue is also legitimate, because if an attacker knows that you're sending over a filename that requires unescaping, they can plant a file with the escaped file name (e.g., literally called This%20Has%20Spaces.jpg -- remember, % is a valid filename character!) and it will be loaded instead of the intended file ("This Has Spaces.jpg"). There needs to be a way to unambiguously specify the filename. I'm open to suggestions.

 

It's easy enough to change the error dialogs to include file names and exception details... I think. I'd have to double check. Not having the file name in there has long been something I've thought should be included but I haven't taken the time to do it. 

 

4.2.11 is going out soon, this may be easy to sneak in. But, protocol stuff has proven to be super bi***y to get right -- like some whack-a-mole game, you kill 1 bug and 1 more immediately pops up. However, I don't think any changes here are actually specific to protocol handling ... although maybe the registry entries should just include a /protocol switch so that the app actually knows it's being launched via protocol.

  • Like 1

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to post
Share on other sites

My proposal is this: if you need url decoding, which is where all those %'s come from, then you can prefix the file name with url: . This has the advantage of using a character that isn't valid for file names (colon). The remainder of the parameter will be url decoded via WebUtility.UrlDecode.

 

It will still be considered one command-line argument, so quotation marks would go around the whole thing, not just the filename after the url:. However, since spaces should turn into %20, I don't think quotes would be needed.

 

I can put this into the next 4.2.11 build that I"ll be putting out ... probably tomorrow.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...