GeorgeHope Posted April 17, 2020 Share Posted April 17, 2020 (edited) 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 April 17, 2020 by GeorgeHope Skipped minor step in replication setup. Quote Link to comment Share on other sites More sharing options...
Zagna Posted April 17, 2020 Share Posted April 17, 2020 (edited) You could try the paintdotnet: protocol? I got errors as well... maybe just HTTP paths just can't be used. Edited April 17, 2020 by Zagna Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted April 17, 2020 Share Posted April 17, 2020 Why are you creating your own protocol for this? Just use the built-in paintdotnet: protocol. 2 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
GeorgeHope Posted April 19, 2020 Author Share Posted April 19, 2020 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; https://docs.microsoft.com/en-us/dotnet/api/system.io.path.directoryseparatorchar?view=netframework-4.8 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 Quote Link to comment Share on other sites More sharing options...
BoltBait Posted April 19, 2020 Share Posted April 19, 2020 Did you try: paintdotnet:"D:/!Geo/Test Me Spaces/Galaxy_ValdayDrift.pdn" 2 Quote Click to play: Download: BoltBait's Plugin Pack | CodeLab | and how about a Computer Dominos Game Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted April 19, 2020 Share Posted April 19, 2020 ^ 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....) Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
Rick Brewster Posted April 19, 2020 Share Posted April 19, 2020 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. 1 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
GeorgeHope Posted April 19, 2020 Author Share Posted April 19, 2020 (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: Edited April 19, 2020 by GeorgeHope Minor Clarification of Issue Quote Link to comment Share on other sites More sharing options...
GeorgeHope Posted April 27, 2020 Author Share Posted April 27, 2020 @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. Quote Link to comment Share on other sites More sharing options...
null54 Posted April 27, 2020 Share Posted April 27, 2020 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? Quote Plugin Pack | PSFilterPdn | Content Aware Fill | G'MIC | Paint 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 comment Share on other sites More sharing options...
GeorgeHope Posted April 27, 2020 Author Share Posted April 27, 2020 (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 April 27, 2020 by GeorgeHope Added commentary on intent. 1 Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted April 27, 2020 Share Posted April 27, 2020 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. 1 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Rick Brewster Posted April 28, 2020 Share Posted April 28, 2020 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. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.