Documentation
¶
Overview ¶
Package view provides customisable abstractions over collections. Changes to an underlying collection are reflected in its views, and vice-versa.
Example (UrlQuery) ¶
package main import ( "fmt" "net/url" "path" "sort" "github.com/acarl005/stripansi" "github.com/tawesoft/golib/v2/view" ) // Untrusted applies visible runtime tainting of untrusted values (as // recommended by OWASP). This means we are unable to use an untrusted // input accidentally, and must first access it using an escape function. type Untrusted struct { value string } func (u Untrusted) Raw() string { return u.value } func (u Untrusted) Escape(esc ...func(x string) string) string { result := u.value for _, escaper := range esc { result = escaper(result) } return result } func UntrustedString(x string) Untrusted { return Untrusted{x} } func main() { // Assume an input URL query from an intrusted source args := url.Values{} // map[string][]string args.Set("name", "Ava") args.Add("friend", "Jess") args.Add("friend", "Sarah") args.Add("friend", "Zoe") args.Add("filename", "../index.html") // malicious input args.Add("fbclid", "nonsense we don't care about") // args.Encode() == ... recognisedKeys := []string{"name", "friend", "filename"} sort.Strings(recognisedKeys) onlyRecognised := func(k string, _ []string) bool { i := sort.SearchStrings(recognisedKeys, k) return (i < len(recognisedKeys)) && (recognisedKeys[i] == k) } // Construct a view that can read keys and values from the input query, // wrapping them in the Untrusted type. Additionally, we filter only // the keys we care about. // // Like the url.Values.Get method, returns only the first value associated // with the given key. taintedValues := view.Map[string, []string, Untrusted, Untrusted]{ Filterer: onlyRecognised, ToKey: func(k string) Untrusted { return UntrustedString(k) }, FromKey: func(k Untrusted) string { return k.Raw() }, ToValue: func(x []string) Untrusted { if len(x) >= 1 { return UntrustedString(x[0]) } return Untrusted{} }, FromValue: nil, // omitted as we don't need to map a value back }.Bind(args) if name, ok := taintedValues.Get(UntrustedString("name")); ok { fmt.Printf("Hi %s!\n", name.Escape(stripansi.Strip)) } else { fmt.Printf("Hello anonymous!\n") } if friend, ok := taintedValues.Get(UntrustedString("friend")); ok { fmt.Printf("I see that you're friends with %s!\n", friend.Escape(stripansi.Strip)) } if filename, ok := taintedValues.Get(UntrustedString("filename")); ok { // NOTE: this is an example only and is not complete as there are still // other ways the path could be unsafe. fmt.Printf("Safe filename: %s\n", filename.Escape(path.Clean, path.Base, stripansi.Strip)) } else { fmt.Printf("No file specified.\n") } if _, ok := taintedValues.Get(UntrustedString("fbclid")); ok { panic("Didn't expect to see this!") } }
Output: Hi Ava! I see that you're friends with Jess! Safe filename: index.html
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Map ¶ added in v2.7.0
type Map[K comparable, V any, ToK comparable, ToV any] struct { // Filterer defines a function that controls, given an element (key, value) // pair from the underlying collection, whether that element is mapped // to the new collection in Get or Iter methods on a View. Elements only // appear if the filter function returns true. If omitted, defaults to a // function that always returns true. Filterer func(K, V) bool // ToKey defines a function that maps K to ToK. ToKey func(K) ToK // FromKey defines the inverse of ToKey. FromKey func(ToK) K // ToValue defines a function that maps V to ToV. ToValue func(V) ToV // FromValue defines the inverse of ToValue. // Note that FromValue may be omitted if the [View.Set] method is never // called. FromValue func(ToV) V }
Map describes a way to create a View from a Go map collection type that maps to a collection of mapped keys and values.
The types K and V define element types in an original collection. The types ToK and ToV define element types in a new collection formed by mapping K to ToK and mapping v to ToV.
type Slice ¶ added in v2.7.0
type Slice[V any, ToV any] struct { // Filterer defines a function that controls, given a value from the // underlying collection, whether that element is mapped to the new // collection in Get or Iter methods on a View. Values only appear if the // filter function returns true. If omitted, defaults to a function that // always returns true. Filterer func(V) bool // ToValue defines a function that maps V to ToV. ToValue func(V) ToV // FromValue defines the inverse of ToValue. // Note that FromValue may be omitted if the [View.Set] method is never // called. FromValue func(ToV) V }
Slice describes a way to create a View from a Go slice collection type that maps to a collection of mapped values.
The type V defines element types in an original collection. The type ToV defines element types in a new collection formed by mapping v to ToV.
type View ¶
type View[K comparable, V any] interface { Get(K) (V, bool) Set(K, V) Delete(K) Iter() iter.It[iter.Pair[K, V]] }
View is an abstraction over a collection. In the case of a slice, the key is an int representing the index.
type Viewer ¶ added in v2.7.0
type Viewer[K comparable, V any, ToK comparable, ToV any] struct { // Filterer defines a function that controls, given an element (key, value) // pair from the underlying collection, whether that element is mapped // to the new collection in Get or Iter methods on a View. Elements only // appear if the filter function returns true. If omitted, defaults to a // function that always returns true. Filterer func(K, V) bool // Getter defines a function that accesses a given value from the underlying // collection. It is implemented in terms of the types of the underlying // collection, and should not implement the filtering itself. Getter func(K) (V, bool) // Setter defines a function that sets a given value in the underlying // collection. It is implemented in terms of the types of the underlying // collection, and ignores filtering. Setter func(K, V) // Deleter defines a function that deletes a given value in the underlying // collection. It is implemented in terms of the types of the underlying // collection, and ignores filtering. Deleter func(K) // ToKey defines a function that maps K to ToK. ToKey func(K) ToK // FromKey defines the inverse of ToKey. FromKey func(ToK) K // ToValue defines a function that maps V to ToV. ToValue func(V) ToV // FromValue defines the inverse of ToValue. // Note that FromValue may be omitted if FromValue func(ToV) V // Iterer defines a function that returns a new iterator over the underlying // collection. It is implemented in terms of the types of the underlying // collection, and should not implement the filtering itself. Iterer func() iter.It[iter.Pair[K, V]] }
Viewer describes a View over a Go collection type that maps to a new collection of mapped keys and values.
This is a generic, low-level definition for implementors of custom collection types. Most users will want to call the Bind method on the simpler Map or Slice constructor types instead.
func (Viewer[K, V, ToK, ToV]) Delete ¶ added in v2.7.0
func (m Viewer[K, V, ToK, ToV]) Delete(k ToK)