Documentation ¶
Overview ¶
Package permission implements the data structures and algorithms for parsing permission annotations, infering permissions, and checking permissions for correctness.
Index ¶
- func CopyableTo(A, B Permission) bool
- func IsLinear(p Permission) bool
- func MovableTo(A, B Permission) bool
- func RefcopyableTo(A, B Permission) bool
- type ArrayPermission
- type BasePermission
- type ChanPermission
- type FuncPermission
- type InterfacePermission
- type MapPermission
- type NilPermission
- type Parser
- type Permission
- func ConvertTo(perm Permission, goal Permission) (result Permission, err error)
- func ConvertToBase(perm Permission, goal BasePermission) Permission
- func Intersect(perm Permission, goal Permission) (result Permission, err error)
- func StrictConvertToBase(perm Permission, goal BasePermission) Permission
- func Union(perm Permission, goal Permission) (result Permission, err error)
- type PointerPermission
- type Scanner
- type SlicePermission
- type StructPermission
- type Token
- type TokenType
- type TuplePermission
- type TypeMapper
- type WildcardPermission
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CopyableTo ¶
func CopyableTo(A, B Permission) bool
CopyableTo checks whether an object with permission A be copied into an object with permission B. The base requirement is that A is readable, or both have no permissions.
func MovableTo ¶
func MovableTo(A, B Permission) bool
MovableTo checks that a capability of permission A can be moved to a capability with permission B.
A move is only allowed if the permissions of the target are narrower than the permission of the source. Values can be copied, however: A copy of a value might have a larger set of permissions - see CopyableTo()
func RefcopyableTo ¶
func RefcopyableTo(A, B Permission) bool
RefcopyableTo checks whether an object with permission A can also be referenced by a permission B. It is generally like move, with two differences:
1. A may be unreadable 2. A and B may not be linear
Types ¶
type ArrayPermission ¶
type ArrayPermission struct { BasePermission BasePermission // The permission on the array/slice value itself ElementPermission Permission // The permission of the elements it contains }
ArrayPermission describes permissions on arrays
func (*ArrayPermission) GetBasePermission ¶
func (p *ArrayPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type BasePermission ¶
type BasePermission int
BasePermission represents a set of read, write, owned, and exclusive flags, describing how a value may be used.
const ( // Owned means that the value is owned. An unowned value cannot be stored // into an owned value, essentially. Owned BasePermission = 1 << iota // Read means the value can be read from. Read BasePermission = 1 << iota // Write means the value can be written from Write BasePermission = 1 << iota // ExclRead is the exclusive read permission, meaning no other alias has // read access. It does not imply read permission. ExclRead BasePermission = 1 << iota // ExclWrite is the exclusive write permission, meaning no other alias has // write access. It does not imply write permission. ExclWrite BasePermission = 1 << iota )
BasePermission flags. These can be combined via OR to get a usable base permission.
const ( // A linear mutable type Mutable BasePermission = Read | Write | ExclRead | ExclWrite // A linear immutable type LinearValue BasePermission = Read | ExclRead | ExclWrite // A non-linear value type that ensures nobody else is writing to the // value. Value BasePermission = Read | ExclWrite // A non-linear read-only reference to a value that might be written from // other references. TODO: Does this permission even make sense? ReadOnly BasePermission = Read // Unsafe: Any is used for return values of external Go functions. Any BasePermission = Owned | Read | Write // Unsafe: None is used for parameters of external Go functions. None BasePermission = 0 )
The basic builtin shortcuts to permissions.
func (BasePermission) GetBasePermission ¶
func (perm BasePermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
func (BasePermission) String ¶
func (perm BasePermission) String() string
String renders the base permission in its Canonical form.
type ChanPermission ¶
type ChanPermission struct { BasePermission BasePermission // The permission on the chan value itself ElementPermission Permission // The permission of the elements it contains }
ChanPermission describes permissions on channels and their elements.
func (*ChanPermission) GetBasePermission ¶
func (p *ChanPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type FuncPermission ¶
type FuncPermission struct { BasePermission BasePermission // Permission of the function itself Name string // optional name Receivers []Permission // Permissions of the receiver Params []Permission // Permissions of the parameters Results []Permission // Permissions of results }
FuncPermission describes permissions of functions
func (*FuncPermission) GetBasePermission ¶
func (p *FuncPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type InterfacePermission ¶
type InterfacePermission struct { BasePermission BasePermission // Permission of the interface itself Methods []*FuncPermission // Permission of the methods }
InterfacePermission manages permissions on an interface.
func (*InterfacePermission) GetBasePermission ¶
func (p *InterfacePermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type MapPermission ¶
type MapPermission struct { BasePermission BasePermission // The permission of the map itself KeyPermission Permission // The permission of contained keys ValuePermission Permission // The permission of contained values }
MapPermission describes permissions on map values, their keys and values.
func (*MapPermission) GetBasePermission ¶
func (p *MapPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type NilPermission ¶
type NilPermission struct{}
NilPermission is the permission for nil. It can be assigned anywhere
func (*NilPermission) GetBasePermission ¶
func (p *NilPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser is a parser for the permission syntax.
This parser is implemented as a simple recursive parser, it has horrible error reporting, but it works, and has a test suite.
The parser requires one lookahead token in the scanner.
func (*Parser) Parse ¶
func (p *Parser) Parse() (perm Permission, err error)
Parse parses the permission specification language.
@syntax main <- inner EOF
type Permission ¶
type Permission interface { GetBasePermission() BasePermission // contains filtered or unexported methods }
Permission is an entity associated with an value that describes in which ways the value can be used.
func ConvertTo ¶
func ConvertTo(perm Permission, goal Permission) (result Permission, err error)
ConvertTo takes a permission and makes it compatible with the goal permission. It's use is to turn incomplete annotations into permissions matching the type. For example, if there is a list with a next pointer: it could be annotated "om struct { om }". That is incomplete: The inner "om" refers to a list as well, so the permission needs to be recursive.
By taking the type permission, which is "p = om struct { p }", that is a recursive permission refering to itself, and converting that to the - target, we can make the permission complete.
goal can be either a base permission, or, alternatively, a permission of the same shape as perm. In the latter case, goal must be a consistent permission: It must be made compatible to its base permission, otherwise the result of this function causes undefined behavior.
func ConvertToBase ¶
func ConvertToBase(perm Permission, goal BasePermission) Permission
ConvertToBase converts a permission to a base permission, by limiting all inner permissions to make things consistent.
func Intersect ¶
func Intersect(perm Permission, goal Permission) (result Permission, err error)
Intersect takes two permissions and returns a permission that is a subset of both. An intersection can be used to join permissions from two branches: Given if { v has permission A } else { v has permission B }, the permission for v afterwards will be Intersect(A, B).
func StrictConvertToBase ¶
func StrictConvertToBase(perm Permission, goal BasePermission) Permission
StrictConvertToBase makes sure that the actual permissions of the object only depend on the goal - all base permissions are replaced by the goal.
This is necessary to ensure safe conversions from interfaces to concrete types.
func Union ¶
func Union(perm Permission, goal Permission) (result Permission, err error)
Union takes two permissions and returns a permission that is a superset of both permissions. It exists mostly to allow intersecting function values: For parameters, we need to calculate unions when intersecting (and vice versa). Imagine func(om) and func(or): If we have code that wants to use either of those, we need to have a func(om) - after all, we cannot pass a readable object to a function expecting a writable one, but removing permissions is fine.
type PointerPermission ¶
type PointerPermission struct { BasePermission BasePermission // The permission on the pointer value itself Target Permission // The permission of the value we are pointing to }
PointerPermission describes permissions on a pointer value.
func (*PointerPermission) GetBasePermission ¶
func (p *PointerPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner scans input for tokens used in the permission description language.
It provides a single lookahead token to use.
func (*Scanner) Accept ¶
Accept peeks the next token and if its type matches one of the types specified as an argument, scans and returns it.
type SlicePermission ¶
type SlicePermission struct { BasePermission BasePermission // The permission on the array/slice value itself ElementPermission Permission // The permission of the elements it contains }
SlicePermission describes permissions on slices
func (*SlicePermission) GetBasePermission ¶
func (p *SlicePermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type StructPermission ¶
type StructPermission struct { BasePermission BasePermission // Permission of the struct itself Fields []Permission // Permissions of the fields, in order }
StructPermission describes permissions of structs.
func (*StructPermission) GetBasePermission ¶
func (p *StructPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type TokenType ¶
type TokenType int
TokenType is the type of a token. Valid values are given in the enumeration below.
const ( TokenEndOfFile TokenType = iota // End of file or error TokenParenLeft // Opening parenthesis. TokenParenRight // Closing parenthesis. TokenComma // A Comma TokenWord // A word (string of letters) TokenFunc // The word "func" TokenInterface // The word "interface" TokenMap // The word "map" TokenChan // The word "chan" TokenError // The word "error" (for testing) TokenStruct // The word "struct" TokenNumber // A number (string of digits) TokenStar // The character "*" TokenBracketLeft // The character "[" TokenBracketRight // The character "]" TokenBraceLeft // The character '{' TokenBraceRight // The character '}' TokenSemicolon // The character ';' TokenWildcard // The character '_' )
Token types. These shall become private at some point.
type TuplePermission ¶
type TuplePermission struct { BasePermission BasePermission Elements []Permission }
TuplePermission is used for the result of function calls.
func (*TuplePermission) GetBasePermission ¶
func (p *TuplePermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission
type TypeMapper ¶
type TypeMapper map[types.Type]Permission
TypeMapper maintains a map from types to permissions, so recursive types and type references can be handled correctly.
func (TypeMapper) NewFromType ¶
func (typeMapper TypeMapper) NewFromType(t0 types.Type) (result Permission)
NewFromType constructs a new permission that is as permissive as possible for a given type.
TODO ownership
type WildcardPermission ¶
type WildcardPermission struct { }
WildcardPermission is a permission that can be merged or converted to/from anything and yields the other thing - it is the neutral element for intersection, union, and conversion.
func (*WildcardPermission) GetBasePermission ¶
func (p *WildcardPermission) GetBasePermission() BasePermission
GetBasePermission gets the base permission