peteraritchie / LongPath

drop-in library to support long paths in .NET
GNU Lesser General Public License v3.0
112 stars 43 forks source link

Path.GetDirectoryName returns an absolute path when the input path is relative #7

Closed thomaslevesque closed 9 years ago

thomaslevesque commented 10 years ago

When we pass a relative path to Pri.LongPath.Path.GetDirectoryName, it returns an absolute path based on the current directory; it should return a relative path.

System.IO.Path.GetDirectoryName(@"foo\bar\baz") // "foo\bar"
Pri.LongPath.Path.GetDirectoryName(@"foo\bar\baz") // "C:\CurrentDir\foo\bar"
thomaslevesque commented 10 years ago

Actually, I think the problem is not limited to GetDirectoryName; it's the NormalizePath method that turns the path into an absolute path, and it's called everywhere. So basically, the library doesn't support relative paths at all...

thomaslevesque commented 10 years ago

OK, perhaps I was overly pessimistic... It's not as bad as I thought. The only affected methods were GetDirectoryName and GetPathRoot. I commited a fix and some extra unit tests (I also added a test for Combine which might have been affected, but it was working fine)

peteraritchie commented 10 years ago

Thanks, I'll have a look.

thomaslevesque commented 10 years ago

I just stumbled upon this:

Multithreaded applications and shared library code should not use the GetFullPathName function and should avoid using relative path names.

But NormalizeLongPath relies on GetFullPathName, and it's used everywhere...

The trouble is that for a relative path, GetFullPathName uses the current directory to get the full path, and the current directory is set for the whole process, not for each thread; this makes this API inherently not thread-safe. I'm afraid the only way is to implement NormalizeLongPath manually, rather than relying on GetFullPathName (I looked at the BCL implementation of NormalizePath, it's a bit scary....)

thomaslevesque commented 9 years ago

Just thinking: now that the reference source is under MIT license, it becomes possible to reuse part of the code from .NET to implement this properly :)

peteraritchie commented 9 years ago

NormalizeLongPath has to call GetFullPathName in case a relative path was passed in. I see no way around that.

peteraritchie commented 9 years ago

Merged PR ef12954f4c427d289edba6cab7adf5f685c58de8