Skip to content

Fixes to parentDirectory() and abspath()#533

Merged
satherton merged 14 commits into
apple:masterfrom
ajbeamon:fix-parent-directory
Mar 23, 2019
Merged

Fixes to parentDirectory() and abspath()#533
satherton merged 14 commits into
apple:masterfrom
ajbeamon:fix-parent-directory

Conversation

@ajbeamon

@ajbeamon ajbeamon commented Jun 26, 2018

Copy link
Copy Markdown
Contributor

parentDirectory() and abspath() can now optionally resolve symbolic links and/or require the given path to exist. All ".." and "." references will now be fully resolved by both functions even if the path doesn't fully exist (if the mustExist flag allows success in this case). The following inputs are now handled correctly:

  • paths that are direct children of root
  • paths where not all components exist but which contain .. references after the prefix that does exist
  • absolute paths where no path components exist

…rectory. Also works when the path has trailing slashes.
@ajbeamon ajbeamon requested a review from satherton June 26, 2018 23:34
@ajbeamon ajbeamon added this to the 6.0 milestone Jun 28, 2018
@ajbeamon

ajbeamon commented Jun 28, 2018

Copy link
Copy Markdown
Contributor Author

As stated above, I currently have this open against 5.2. I marked it with the 6.0 milestone so it will hopefully get attention while I'm out, but if we don't feel comfortable enough with it by the time we want to make the release, it could be considered for a future patch release.

@satherton satherton changed the base branch from release-5.2 to release-6.0 July 5, 2018 18:17
@satherton satherton changed the base branch from release-6.0 to master July 5, 2018 18:17
@satherton satherton changed the base branch from master to release-6.0 July 5, 2018 18:18
@satherton satherton modified the milestones: 6.0, 6.1 Jul 10, 2018
# Conflicts:
#	flow/Platform.cpp
@ajbeamon ajbeamon changed the base branch from release-6.0 to master March 15, 2019 17:53
@ajbeamon

Copy link
Copy Markdown
Contributor Author

I've merged in master and switched the base branch from release-6.0 to master.

@satherton satherton self-requested a review March 15, 2019 20:03
Comment thread flow/Platform.cpp Outdated
Comment thread fdbmonitor/fdbmonitor.cpp Outdated
@satherton

satherton commented Mar 15, 2019

Copy link
Copy Markdown
Contributor

It's a bit unclear, and undocumented, exactly what behavior we want from parentDirectory() in context (fdbmonitor and flow/platform). Points to consider,

  • Should the input path be required to exist on the filesystem already?
  • Should relative input paths be supported?
  • Should the empty string input (arguably a form of relative input meaning the current directory) be supported?
  • Should the output always contain a trailing slash? (A useful property bit differs from realpath() behavior..)
  • Is the parent of root an error or an empty result?
  • Should the result have duplicate path separators removed?
  • Should the result have symbolic links resolved to their absolute paths a la realpath()?
  • Should the result have ../ and ./ references resolved?

For inputs that actually exist, using realpath() is a good way to get a canonical path from which a parent can be found easily as it resolves ./ and ../ references and removes trailing and duplicate separators. However, the caller may wish to preserve symbolic links in the input so it can monitor the parent directory symlink for changes (fdbmonitor does this). While parentDirectory exists in fdbmonitor independently from flow/platform, it would be nice if one function definition could satisfy all use cases, perhaps with parameters. And of course there is reason for parentDirectory to work on input strings that do not actually exist on the filesystem.

We should probably revisit abspath() behavior as well. Currently, abspath("/blah") returns "/blah" if /blah exists on the filesystem, and otherwise returns "<absolute_path_of_current_working_directory>/blah" which doesn't seem right for any use case. Also, abspath() will not remove trailing separators for paths that do not exist.

Stephen Atherton added 2 commits March 15, 2019 23:54
…, or duplicate separators without using the filesystem or resolving symbolic links. absPath() redefined to use cleanPath() so it will return the same result for a path without symbolic links regardless of whether or not the path actually exists. Redefined parentDirectory() to use absPath() and error on certain inputs. Added comments describing behavior of these functions, and added a unit test which verbosely tests many inputs to them.
@satherton

Copy link
Copy Markdown
Contributor

I've committed a significant refactoring which I think makes absPath() and parentDirectory() behave in sensible ways. They each use a new platform function called cleanPath() which canonicalizes a path without consulting the filesystem. Among the more serious bad behaviors fixed, it is no longer the case that you get a different result for abspath("/path/to") or parentDirectory("/path/to") based on whether or not "/path/to" actually exists.

The main thing to review is the unit test at the end of Platform.cpp and its output. I'm certain there are still edge cases to add. For convenience, here is the current output:

PASS: cleanPath('') -> ''
PASS: cleanPath('') -> ''
PASS: cleanPath('/') -> '/'
PASS: cleanPath('///.///') -> '/'
PASS: cleanPath('/a/b/.././../c/./././////./d/..//') -> '/c'
PASS: cleanPath('a/b/.././../c/./././////./d/..//') -> 'c'
PASS: cleanPath('..') -> '..'
PASS: cleanPath('../.././') -> '../..'
PASS: cleanPath('../a/b/..//') -> '../a'
PASS: cleanPath('a/b/.././../c/./././////./d/..//..') -> ''
PASS: cleanPath('/..') -> Platform error
PASS: cleanPath('/a/b/../.././../') -> Platform error
PASS: abspath('') -> Platform error
PASS: abspath('/') -> '/'
PASS: abspath('/dev') -> '/dev'
PASS: abspath('/dev/') -> '/dev'
PASS: abspath('/dev/..') -> '/'
PASS: abspath('/dev/../') -> '/'
PASS: abspath('/dev/../') -> '/'
PASS: abspath('/dev/..///') -> '/'
PASS: abspath('blahfoo') -> '/Users/Steve/foundation/foundationdb.clean/blahfoo'
PASS: abspath('blahfoo/bar') -> '/Users/Steve/foundation/foundationdb.clean/blahfoo/bar'
PASS: abspath('blahfoo/bar/') -> '/Users/Steve/foundation/foundationdb.clean/blahfoo/bar'
PASS: abspath('blahfoo/bar/..//') -> '/Users/Steve/foundation/foundationdb.clean/blahfoo'
PASS: abspath('blahfoo/bar/..//../') -> '/Users/Steve/foundation/foundationdb.clean'
PASS: abspath('/blahfoo') -> '/blahfoo'
PASS: abspath('/blahfoo/bar') -> '/blahfoo/bar'
PASS: abspath('/blahfoo/bar/') -> '/blahfoo/bar'
PASS: parentDirectory('') -> Platform error
PASS: parentDirectory('/') -> Platform error
PASS: parentDirectory('//') -> Platform error
PASS: parentDirectory('/a') -> '/'
PASS: parentDirectory('/a/') -> '/'
PASS: parentDirectory('/a/b') -> '/a/'
PASS: parentDirectory('/a/b/c/.././') -> '/a/'
PASS: parentDirectory('a/b/c/.././') -> '/Users/Steve/foundation/foundationdb.clean/a/'

Comment thread flow/Platform.cpp Outdated
Comment thread flow/Platform.cpp
Comment thread flow/Platform.cpp Outdated
@satherton

Copy link
Copy Markdown
Contributor

cleanPath() should probably handle '/' as well regardless of what the canonical separator is. On windows, cleanPath() would not work for fully qualified network paths which begin with '\'.

@satherton

satherton commented Mar 17, 2019

Copy link
Copy Markdown
Contributor

It should probably be the case that
cleanPath(x) == cleanPath(cleanPath(x))
since it is supposed to return a canonical form, so cleanPath(".") should be "." and not "" as it is currently.

Stephen Atherton added 2 commits March 17, 2019 15:58
…ot resolve symbolic links, making it suitable for use in fdbmonitor. CleanPath() will return "." instead of empty string to mean a relative path that refers to the current directory. Updated tests, and added new tests for ".".
…bolic links should be resolved when possible and whether the final resolved path must actually exist on the filesystem. Updated tests, added more cases.
…path() and parentDirectory() implementations from flow.
@satherton satherton changed the title Fixes parentDirectory to work when our path is a child of the root directory. Fixes to parentDirectory() and abspath() Mar 21, 2019
Comment thread flow/Platform.cpp Outdated
Comment thread fdbmonitor/fdbmonitor.cpp Outdated
Comment thread fdbmonitor/fdbmonitor.cpp
Comment thread fdbmonitor/fdbmonitor.cpp Outdated
Comment thread fdbmonitor/fdbmonitor.cpp
Comment thread flow/Platform.h Outdated
Comment thread flow/Platform.cpp Outdated
Comment thread flow/Platform.cpp Outdated
Comment thread flow/Platform.cpp
Comment thread flow/Platform.cpp Outdated
Stephen Atherton added 3 commits March 21, 2019 16:56
… prepend current working directory even when not resolving symlinks. Added more unit tests. Ported path operation unit tests to fdbmonitor() since the path manipulation function implementations are significantly different. Clarified some comments. The flow project version of abspath() does not allow resolveLinks to be false, for now, because behavior of this on Windows is not well thought out or tested.
…d commented call to testPathOps() for convenience.
Comment thread flow/Platform.cpp
Comment thread fdbmonitor/fdbmonitor.cpp
… it only treats ~ as special if it is the first character.
Comment thread flow/Platform.cpp Outdated

@ajbeamon ajbeamon left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GitHub UI won't let me approve because I originated this PR, but it looks good to me. Feel free to merge when the build checks are finished.

@satherton satherton merged commit 09f37cf into apple:master Mar 23, 2019
etschannen pushed a commit to etschannen/foundationdb that referenced this pull request Mar 26, 2019
Fixes to parentDirectory() and abspath()
etschannen pushed a commit to etschannen/foundationdb that referenced this pull request Mar 26, 2019
Fixes to parentDirectory() and abspath()
alexmiller-apple pushed a commit to etschannen/foundationdb that referenced this pull request Mar 26, 2019
Fixes to parentDirectory() and abspath()
@ajbeamon ajbeamon deleted the fix-parent-directory branch March 26, 2019 16:04
sfc-gh-tclinkenbeard pushed a commit to sfc-gh-tclinkenbeard/foundationdb that referenced this pull request Sep 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants