permission

package
v0.0.0-...-03c9e7a Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2017 License: BSD-2-Clause Imports: 6 Imported by: 0

Documentation

Overview

Package permission implements the data structures and algorithms for parsing permission annotations, infering permissions, and checking permissions for correctness.

Index

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 IsLinear

func IsLinear(p Permission) bool

IsLinear checks if a permission is linear.

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

func (*NilPermission) String

func (p *NilPermission) String() string

String gives a nice name

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 NewParser

func NewParser(input string) *Parser

NewParser returns a new parser for the permission specification language.

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 NewScanner

func NewScanner(input string) *Scanner

NewScanner creates a new scanner

func (*Scanner) Accept

func (sc *Scanner) Accept(types ...TokenType) (tok Token, ok bool)

Accept peeks the next token and if its type matches one of the types specified as an argument, scans and returns it.

func (*Scanner) Expect

func (sc *Scanner) Expect(types ...TokenType) Token

Expect calls accept and panic()s if Accept fails

func (*Scanner) Peek

func (sc *Scanner) Peek() Token

Peek at the next token.

func (*Scanner) Scan

func (sc *Scanner) Scan() Token

Scan the next token.

func (*Scanner) Unscan

func (sc *Scanner) Unscan(tok Token)

Unscan makes a token available again for Scan()

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 Token

type Token struct {
	Type  TokenType
	Value string
}

Token has a type and a value

func (Token) String

func (tok Token) String() string

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.

func (TokenType) String

func (typ TokenType) String() string

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 NewTypeMapper

func NewTypeMapper() TypeMapper

NewTypeMapper constructs a new type mapper

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

Jump to

Keyboard shortcuts

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