path

package
v0.0.0-...-a9d0937 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 10, 2024 License: Apache-2.0 Imports: 4 Imported by: 15

Documentation

Index

Constants

This section is empty.

Variables

View Source
var EmptyBuilder = Builder{
	// contains filtered or unexported fields
}

EmptyBuilder is a Builder that contains path ".". New instances of Builder that use this path as their starting point can be created by calling EmptyBuilder.Join().

View Source
var RootBuilder = Builder{
	// contains filtered or unexported fields
}

RootBuilder is a Builder that contains path "/". New instances of Builder that use this path as their starting point can be created by calling RootBuilder.Join().

Functions

func GetLocalString

func GetLocalString(s Stringer) (string, error)

GetLocalString converts a path to a string representation that is supported by the locally running operating system.

func Resolve

func Resolve(parser Parser, scopeWalker ScopeWalker) error

Resolve a pathname string, similar to how the namei() function would work in the kernel. For every productive component in the pathname, a call against a ScopeWalker or ComponentWalker object is made. This object is responsible for registering the path traversal and returning symbolic link contents. Unix-style paths can be created with NewUNIXParser.

This function only implements the core algorithm for path resolution. Features like symlink loop detection, chrooting, etc. should all be implemented as decorators for ScopeWalker and ComponentWalker.

Types

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder for normalized pathname strings.

Instead of providing its own API for constructing paths, every Builder is created with an associated decorator for ScopeWalker. This means that Builder can, for example, be used to record the path traversed by Resolve(), similar to Go's filepath.EvalSymlinks() and libc's realpath().

If there is no need to take the state of the file system into account, it's possible to let the Builder decorate VoidScopeWalker. This allows the construction of paths that don't exist (yet). In that case, unnecessary ".." components are retained, as preceding pathname components may refer to symlinks when applied against an actual file system.

func (*Builder) GetUNIXString

func (b *Builder) GetUNIXString() string

GetUNIXString returns a string representation of the path for use on UNIX-like operating systems.

func (*Builder) Join

func (b *Builder) Join(scopeWalker ScopeWalker) (*Builder, ScopeWalker)

Join another path with the results computed thus far.

This function returns a copy of Builder and ScopeWalker that can be used to compute a path relative to the path computed thus far. If the newly provided path is relative, it is concatenated to the existing path. A trailing slash is appended to the original path. This is done to enforce that the original path is a directory.

If the newly provided path is absolute, it replaces the original path entirely. If this needs to be prevented, it's possible to provide a ScopeWalker that was created using NewRelativeScopeWalker().

func (*Builder) ParseScope

func (b *Builder) ParseScope(scopeWalker ScopeWalker) (next ComponentWalker, remainder RelativeParser, err error)

ParseScope is provided, so that Builder implements the Parser interface. This makes it possible to pass instances of Builder directly to Resolve(). This can be used to replay resolution of a previously constructed path.

type Component

type Component struct {
	// contains filtered or unexported fields
}

Component of a pathname. This type is nothing more than a string that is guaranteed to be a valid Unix filename.

func MustNewComponent

func MustNewComponent(name string) Component

MustNewComponent is identical to NewComponent, except that it panics upon failure.

func NewComponent

func NewComponent(name string) (Component, bool)

NewComponent creates a new pathname component. Creation fails in case the name is empty, ".", "..", contains a slash, or is not a valid C string.

func (Component) String

func (c Component) String() string

type ComponentWalker

type ComponentWalker interface {
	// OnDirectory is called for every pathname component that must
	// resolve to a directory or a symbolic link to a directory.
	//
	// If the pathname component refers to a directory, this function
	// will return a GotDirectory containing a new ComponentWalker
	// against which successive pathname components can be resolved.
	//
	// If the pathname component refers to a symbolic link, this
	// function will return a GotSymlink containing a ScopeWalker, which
	// can be used to perform expansion of the symbolic link. The
	// Resolve() function will call into OnAbsolute() or OnRelative() to
	// signal whether resolution should continue at the root directory
	// or at the directory that contained the symbolic link.
	OnDirectory(name Component) (GotDirectoryOrSymlink, error)

	// OnTerminal is called for the potentially last pathname
	// component that needs to be resolved. It may resolve to any
	// kind of file.
	//
	// If the pathname component does not refer to a symbolic link,
	// the function will return nil. This causes Resolve() to assume
	// that pathname resolution has completed.
	//
	// If the pathname component refers to a symbolic link, this
	// function will return a GotSymlink, just like OnDirectory()
	// does. This causes Resolve() to continue the resolution
	// process.
	OnTerminal(name Component) (*GotSymlink, error)

	// OnUp is called if a ".." pathname component is observed.
	OnUp() (ComponentWalker, error)
}

ComponentWalker is an interface that is called into by Resolve(). An implementation can use it to capture the path that is resolved. ComponentWalker is called into after determining whether the path is absolute or relative (see ScopeWalker). It is called into once for every pathname component that is processed.

Each of ComponentWalker's methods invalidate the object on which it is called. Additional calls must be directed against the ScopeWalkers and ComponentWalkers yielded by these methods.

var VoidComponentWalker ComponentWalker = voidComponentWalker{}

VoidComponentWalker is an instance of ComponentWalker that can resolve any filename. By itself it is of little use. When used in combination with Builder, it can be used to construct arbitrary paths.

type ComponentsList

type ComponentsList []Component

ComponentsList is a sortable list of filenames in a directory.

func (ComponentsList) Len

func (l ComponentsList) Len() int

func (ComponentsList) Less

func (l ComponentsList) Less(i, j int) bool

func (ComponentsList) Swap

func (l ComponentsList) Swap(i, j int)

type GotDirectory

type GotDirectory struct {
	// Child directory against which resolution should continue.
	Child ComponentWalker

	// Whether Child.OnUp() is guaranteed to refer to the same
	// directory. This information can be used by Builder to remove
	// unnecessary ".." pathname components. This should be set to
	// false if paths are not resolved against a concrete file
	// system to ensure ".." components remain present.
	IsReversible bool
}

GotDirectory is returned by ComponentWalker.OnDirectory(), in case the name corresponds to a directory stored in the current directory.

type GotDirectoryOrSymlink interface {
	// contains filtered or unexported methods
}

GotDirectoryOrSymlink is a union type of GotDirectory and GotSymlink. It is returned by ComponentWalker.OnDirectory(), as that function may return either a directory or symbolic link.

type GotSymlink struct {
	// The parent directory of the symbolic link, which is relative
	// to where symlink expansion needs to be performed.
	Parent ScopeWalker

	// The contents of the symbolic link.
	Target Parser
}

GotSymlink is returned by ComponentWalker.OnDirectory() and OnTerminal(), in case the name corresponds to a symbolic link stored in the current directory.

func OnTerminalViaOnDirectory

func OnTerminalViaOnDirectory(cw ComponentWalker, name Component) (*GotSymlink, error)

OnTerminalViaOnDirectory is an implementation of ComponentWalker's OnTerminal() that just calls into OnDirectory(). This is sufficient for implementations of ComponentWalker that only support resolving directories and symbolic links.

type Parser

type Parser interface {
	ParseScope(scopeWalker ScopeWalker) (next ComponentWalker, remainder RelativeParser, err error)
}

Parser is used by Resolve to parse paths in the resolution. Implementations of ParseScope() should return a new copy of Parser and leave the current instance unmodified. It is permitted to call ParseScope() multiple times.

func MustNewUNIXParser

func MustNewUNIXParser(path string) Parser

MustNewUNIXParser is identical to NewUNIXParser, except that it panics upon failure.

func NewLocalParser

func NewLocalParser(path string) (Parser, error)

NewLocalParser creates a pathname parser for paths that are native to the locally running operating system.

func NewUNIXParser

func NewUNIXParser(path string) (Parser, error)

NewUNIXParser creates a Parser for Unix paths that can be used in Resolve.

type RelativeParser

type RelativeParser interface {
	ParseFirstComponent(componentWalker ComponentWalker, mustBeDirectory bool) (next GotDirectoryOrSymlink, remainder RelativeParser, err error)
}

RelativeParser is used by Resolve to parse relative paths in the resolution. Implementations of ParseFirstComponent() should return a new copy of Parser and leave the current instance unmodified. It is permitted to call ParseFirstComponent() multiple times.

type ScopeWalker

type ScopeWalker interface {
	// One of these functions is called right before processing the
	// first component in the path (if any). Based on the
	// characteristics of the path. Absolute paths are handled through
	// OnAbsolute(), and relative paths require OnRelative().
	//
	// These functions can be used by the implementation to determine
	// whether path resolution needs to be relative to the current
	// directory (e.g., working directory or parent directory of the
	// previous symlink encountered) or the root directory.
	//
	// For every instance of ScopeWalker, one of OnAbsolute() or
	// OnRelative() may be called at most once. Resolve() will always
	// call into one of the interface functions for every ScopeWalker
	// presented, though decorators such as
	// VirtualRootScopeWalkerFactory may only call it when the path is
	// known to be valid. Absence of calls to OnAbsolute() or
	// OnRelative() are used to indicate that the provided path does not
	// resolve to a location inside the file
	// system.
	OnAbsolute() (ComponentWalker, error)
	OnRelative() (ComponentWalker, error)
}

ScopeWalker is an interface that is called into by Resolve(). An implementation can use it to capture the path that is resolved. ScopeWalker is called into once for every path that is processed.

var VoidScopeWalker ScopeWalker = voidScopeWalker{}

VoidScopeWalker is an instance of ScopeWalker that accepts both relative and absolute paths, and can resolve any filename. By itself it is of little use. When used in combination with Builder, it can be used to construct arbitrary paths.

func NewAbsoluteScopeWalker

func NewAbsoluteScopeWalker(componentWalker ComponentWalker) ScopeWalker

NewAbsoluteScopeWalker creates a ScopeWalker that only accepts absolute paths.

func NewLoopDetectingScopeWalker

func NewLoopDetectingScopeWalker(base ScopeWalker) ScopeWalker

NewLoopDetectingScopeWalker creates a decorator for ScopeWalker that prevents unlimited expansion of symbolic links by only allowing a finite number of iterations.

This implementation permits up to 40 iterations, which is the same as what Linux supports (MAXSYMLINKS in include/linux/namei.h).

func NewRelativeScopeWalker

func NewRelativeScopeWalker(componentWalker ComponentWalker) ScopeWalker

NewRelativeScopeWalker creates a ScopeWalker that only accepts relative paths.

type Stringer

type Stringer interface {
	GetUNIXString() string
}

Stringer is implemented by path types in this package that can be converted to string representations.

type TerminalNameTrackingComponentWalker

type TerminalNameTrackingComponentWalker struct {
	TerminalName *Component
}

TerminalNameTrackingComponentWalker can be embedded into an implementation of ComponentWalker to provide a default implementation of the OnTerminal() method. OnTerminal() is implemented in such a way that it simply tracks the name.

This implementation is useful for ComponentWalkers that are used to create new files or directories.

func (*TerminalNameTrackingComponentWalker) OnTerminal

OnTerminal records the name of the final component of a path.

type Trace

type Trace struct {
	// contains filtered or unexported fields
}

Trace of a path.

This type can be used to construct normalized relative pathnames. Traces are immutable, though it is possible to append pathname components to them.

A nil pointer corresponds to path ".".

func (*Trace) Append

func (t *Trace) Append(component Component) *Trace

Append a pathname component. The original trace is left intact.

func (*Trace) GetUNIXString

func (t *Trace) GetUNIXString() string

GetUNIXString returns a string representation of the path for use on UNIX-like operating systems.

type VirtualRootScopeWalkerFactory

type VirtualRootScopeWalkerFactory struct {
	// contains filtered or unexported fields
}

VirtualRootScopeWalkerFactory is a factory for decorators for ScopeWalker that place them at a path inside of a virtual file system hierarchy, potentially consisting of one or more symlinks pointing to it.

This type can be used to ensure symlink expansion works properly in case the root of the directory hierarchy that is walked is in reality not the root directory of the system. In this hierarchy there may be symlinks that contain absolute target paths. These can only be resolved properly by trimming one or more leading pathname components.

The underlying implementation of ScopeWalker has the ability to detect whether the resolved path lies inside or outside of the nested directory hierarchy by monitoring whether a ScopeWalker interface method has been called. If this function is called on the wrapped ScopeWalker, but not called on the underlying instance (either initially or after returning a GotSymlink response), the resolved path lies outside the nested root directory.

func NewVirtualRootScopeWalkerFactory

func NewVirtualRootScopeWalkerFactory(rootPath Parser, aliases map[string]string) (*VirtualRootScopeWalkerFactory, error)

NewVirtualRootScopeWalkerFactory creates a VirtualRootScopeWalkerFactory. The rootPath argument denotes an absolute path at which the underlying ScopeWalker should be placed in the virtual file system hierarchy. The aliases argument is a map of absolute paths to relative paths. These are converted to symbolic links that are placed inside the virtual root, pointing to relative locations underneath the ScopeWalker.

For example, if this function is called with rootPath == "/root" and aliases == {"/alias": "target"}, then paths on the outer ScopeWalker resolve to the following locations in the underlying ScopeWalker:

"hello"        -> "hello"
"/root"        -> "/"
"/root/hello"  -> "/hello"
"/alias"       -> "/target"
"/alias/hello" -> "/target/hello"
"/"            -> Nothing
"/hello"       -> Nothing

func (*VirtualRootScopeWalkerFactory) New

New wraps an existing ScopeWalker to place it inside the virtual root.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL