NSURL - is it intended behavior for -URLByAppendingPathComponent: to allow appending multiple path components in one call?

The documentation for NSURL -URLByAppendingPathComponent: states:

"Returns a new URL by appending a path component to the original URL."

Path component is singular. But this "works" :

NSURL *testURL = [applicationsDirectory URLByAppendingPathComponent:@"Evil/../../" isDirectory:YES];

So my questions are:

One) Was it always this way? I can't recall if it was like this before the Foundation rewrite and I just never stumbled across?

and

Two) Is it intended behavior?

The API seems to suggest that you append one path component on the url with this method. But I guess you can append as many as you want?

Thanks fat the post. Interesting observation to an API I used as long as I can remember. Hopefully someone from foundation can jump into this thread. But my question to you is if you have encountered any issues preventing using it?

What is your concern about the API? it’s been working like that since iOS 4 I believe. I’m more interested in how you going to use it.

Yes, it has always been this way, and yes, it is the intended or at least, accepted and long-standing behavior.

https://developer.apple.com/documentation/foundation/nsurl/appendingpathcomponent(_:)?language=objc

It’s an API I have used forever, under the hood in Objective-C, NSURL was CFURL but I haven’t check so do not quote me on that. It treats whatever string you pass it as the "component" to append. If you pass a string containing slashes where developers intentionally appended multiple components at once (e.g., [baseURL URLByAppendingPathComponent:@"Dir/Subdir/file.txt"]).

The documentation provides this note or discussion as it’s called https://developer.apple.com/documentation/foundation/nsurl/appendingpathcomponent(_:)?language=objc#Discussion

Albert 
  Worldwide Developer Relations.

If you pass a string containing slashes where developers intentionally appended multiple components at once (e.g., [baseURL URLByAppendingPathComponent:@"Dir/Subdir/file.txt"]).

Interesting. I did not realize this was intended. I would prefer an explicit -urlByAppendingPathComponents:(NSArray<NSString*>*) method for that use case.

What is your concern about the API?

I actually find that this API accepting this syntax /../../../ to walk parent directories rather terrifying.

As many path components as you want? While that syntax has its uses I think it is extremely rare for developers to use -URLByAppendingPathComponent: intentionally in that way with that purpose in mind. The name of the method implies one I think? And you are most often trying to go forward not backward when you use this API.

Tell Xcode where my headers are use of @".." okay fine but most apps don't do that. IMO that should probably be split into a different API that clearly describes the purpose.

To walk back parent directories the more sane thing to do, in most apps I think is to use URLByDeletingLastPathComponent instead.

If it isn't considered a 'security issue' on its own it at least looks like the seed of one.

I did file FB 22349771 (space intentionally added to avoid moderation flag).

[@Macho Man Randy Savage](https://developer.apple.com/forums/profile/Macho Man Randy Savage) My question reading you FB number is how URLByAppendingPathComponent can be easy target to attack?

Albert 
  Worldwide Developer Relations.

If an app assumes it's appending only one path component on a directory it owns (like inside a package), it may think it is safe, but it can be tricked into overwriting files at unexpected file system locations.

-URLByAppendingPathComponent: is, as the name makes clear, intended to add a single path component. However, it doesn’t do anything to block you from adding a string with a path component separator, which effectively adds multiple path components. This is something I try to avoid relying because it assumes that the path component separator is always /. Way back in the day Foundation used to run on non-Unix-y platforms, where that wasn’t the case. And the Swift equivalent of this method runs on non-Unix-y platforms today.

Notably, the modern Swift equivalent of this method, namely appending(component:directoryHint:), will percent encode path separators.

ps File system paths are a source on ongoing grief. For a clear example of that, read this Swift Forums thread.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

NSURL - is it intended behavior for -URLByAppendingPathComponent: to allow appending multiple path components in one call?
 
 
Q