diff options
author | 2021-12-20 09:35:32 +0000 | |
---|---|---|
committer | 2021-12-20 10:35:32 +0100 | |
commit | 635ad2a42f10a5b24f08021782b71b4cf8326e19 (patch) | |
tree | 3221d2c4526b5214c9a9b9d33343d48b2e9c9649 /vendor/codeberg.org/gruf/go-store | |
parent | Log when listening (#350) (diff) | |
download | gotosocial-635ad2a42f10a5b24f08021782b71b4cf8326e19.tar.xz |
Update codeberg.org/gruf libraries and fix go-store issue (#347)
* update codeberg.org/gruf/ libraries
Signed-off-by: kim <grufwub@gmail.com>
* another update
Signed-off-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/codeberg.org/gruf/go-store')
-rw-r--r-- | vendor/codeberg.org/gruf/go-store/kv/state.go | 63 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-store/kv/store.go | 42 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-store/storage/block.go | 8 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-store/storage/disk.go | 8 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-store/storage/memory.go | 42 | ||||
-rw-r--r-- | vendor/codeberg.org/gruf/go-store/util/fs.go | 20 |
6 files changed, 104 insertions, 79 deletions
diff --git a/vendor/codeberg.org/gruf/go-store/kv/state.go b/vendor/codeberg.org/gruf/go-store/kv/state.go index a8c1b9c82..20a3e951d 100644 --- a/vendor/codeberg.org/gruf/go-store/kv/state.go +++ b/vendor/codeberg.org/gruf/go-store/kv/state.go @@ -2,6 +2,7 @@ package kv import ( "io" + "sync" "codeberg.org/gruf/go-errors" ) @@ -15,9 +16,14 @@ var ErrStateClosed = errors.New("store/kv: state closed") // then the state has zero guarantees type StateRO struct { store *KVStore + mutex sync.RWMutex } func (st *StateRO) Get(key string) ([]byte, error) { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return nil, ErrStateClosed @@ -28,6 +34,10 @@ func (st *StateRO) Get(key string) ([]byte, error) { } func (st *StateRO) GetStream(key string) (io.ReadCloser, error) { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return nil, ErrStateClosed @@ -38,6 +48,10 @@ func (st *StateRO) GetStream(key string) (io.ReadCloser, error) { } func (st *StateRO) Has(key string) (bool, error) { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return false, ErrStateClosed @@ -47,8 +61,16 @@ func (st *StateRO) Has(key string) (bool, error) { return st.store.has(key) } -func (st *StateRO) close() { - st.store = nil +func (st *StateRO) Release() { + // Get state write lock + st.mutex.Lock() + defer st.mutex.Unlock() + + // Release the store + if st.store != nil { + st.store.mutex.RUnlock() + st.store = nil + } } // StateRW provides a read-write window to the store. While this @@ -58,9 +80,14 @@ func (st *StateRO) close() { // then the state has zero guarantees type StateRW struct { store *KVStore + mutex sync.RWMutex } func (st *StateRW) Get(key string) ([]byte, error) { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return nil, ErrStateClosed @@ -71,6 +98,10 @@ func (st *StateRW) Get(key string) ([]byte, error) { } func (st *StateRW) GetStream(key string) (io.ReadCloser, error) { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return nil, ErrStateClosed @@ -81,6 +112,10 @@ func (st *StateRW) GetStream(key string) (io.ReadCloser, error) { } func (st *StateRW) Put(key string, value []byte) error { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return ErrStateClosed @@ -91,6 +126,10 @@ func (st *StateRW) Put(key string, value []byte) error { } func (st *StateRW) PutStream(key string, r io.Reader) error { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return ErrStateClosed @@ -101,6 +140,10 @@ func (st *StateRW) PutStream(key string, r io.Reader) error { } func (st *StateRW) Has(key string) (bool, error) { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return false, ErrStateClosed @@ -111,6 +154,10 @@ func (st *StateRW) Has(key string) (bool, error) { } func (st *StateRW) Delete(key string) error { + // Get state read lock + st.mutex.RLock() + defer st.mutex.RUnlock() + // Check not closed if st.store == nil { return ErrStateClosed @@ -120,6 +167,14 @@ func (st *StateRW) Delete(key string) error { return st.store.delete(key) } -func (st *StateRW) close() { - st.store = nil +func (st *StateRW) Release() { + // Get state write lock + st.mutex.Lock() + defer st.mutex.Unlock() + + // Release the store + if st.store != nil { + st.store.mutex.Unlock() + st.store = nil + } } diff --git a/vendor/codeberg.org/gruf/go-store/kv/store.go b/vendor/codeberg.org/gruf/go-store/kv/store.go index 148e3f33d..34fe91987 100644 --- a/vendor/codeberg.org/gruf/go-store/kv/store.go +++ b/vendor/codeberg.org/gruf/go-store/kv/store.go @@ -212,32 +212,34 @@ func (st *KVStore) Iterator(matchFn func(string) bool) (*KVIterator, error) { }, nil } -// Read provides a read-only window to the store, holding it in a read-locked state until -// the supplied function returns -func (st *KVStore) Read(do func(*StateRO)) { - // Get store read lock +// Read provides a read-only window to the store, holding it in a read-locked state until release +func (st *KVStore) Read() *StateRO { st.mutex.RLock() - defer st.mutex.RUnlock() + return &StateRO{store: st} +} - // Create new store state (defer close) - state := &StateRO{store: st} - defer state.close() +// ReadFn provides a read-only window to the store, holding it in a read-locked state until fn return. +func (st *KVStore) ReadFn(fn func(*StateRO)) { + // Acquire read-only state + state := st.Read() + defer state.Release() - // Pass state - do(state) + // Pass to fn + fn(state) } -// Update provides a read-write window to the store, holding it in a read-write-locked state -// until the supplied functions returns -func (st *KVStore) Update(do func(*StateRW)) { - // Get store lock +// Update provides a read-write window to the store, holding it in a write-locked state until release +func (st *KVStore) Update() *StateRW { st.mutex.Lock() - defer st.mutex.Unlock() + return &StateRW{store: st} +} - // Create new store state (defer close) - state := &StateRW{store: st} - defer state.close() +// UpdateFn provides a read-write window to the store, holding it in a write-locked state until fn return. +func (st *KVStore) UpdateFn(fn func(*StateRW)) { + // Acquire read-write state + state := st.Update() + defer state.Release() - // Pass state - do(state) + // Pass to fn + fn(state) } diff --git a/vendor/codeberg.org/gruf/go-store/storage/block.go b/vendor/codeberg.org/gruf/go-store/storage/block.go index 112b67d80..9a8c4dc7d 100644 --- a/vendor/codeberg.org/gruf/go-store/storage/block.go +++ b/vendor/codeberg.org/gruf/go-store/storage/block.go @@ -585,8 +585,8 @@ func (st *BlockStorage) WalkKeys(opts WalkKeysOptions) error { // nodePathForKey calculates the node file path for supplied key func (st *BlockStorage) nodePathForKey(key string) (string, error) { - // Path separators are illegal - if strings.Contains(key, "/") { + // Path separators are illegal, as directory paths + if strings.Contains(key, "/") || key == "." || key == ".." { return "", ErrInvalidKey } @@ -594,6 +594,10 @@ func (st *BlockStorage) nodePathForKey(key string) (string, error) { pb := util.GetPathBuilder() defer util.PutPathBuilder(pb) + // Append the nodepath to key + pb.AppendString(st.nodePath) + pb.AppendString(key) + // Return joined + cleaned node-path return pb.Join(st.nodePath, key), nil } diff --git a/vendor/codeberg.org/gruf/go-store/storage/disk.go b/vendor/codeberg.org/gruf/go-store/storage/disk.go index cbc365eed..060d56688 100644 --- a/vendor/codeberg.org/gruf/go-store/storage/disk.go +++ b/vendor/codeberg.org/gruf/go-store/storage/disk.go @@ -69,7 +69,6 @@ func getDiskConfig(cfg *DiskConfig) DiskConfig { // DiskStorage is a Storage implementation that stores directly to a filesystem type DiskStorage struct { path string // path is the root path of this store - dots int // dots is the "dotdot" count for the root store path bufp pools.BufferPool // bufp is the buffer pool for this DiskStorage config DiskConfig // cfg is the supplied configuration for this store } @@ -120,7 +119,6 @@ func OpenFile(path string, cfg *DiskConfig) (*DiskStorage, error) { // Return new DiskStorage return &DiskStorage{ path: path, - dots: util.CountDotdots(path), bufp: pools.NewBufferPool(config.WriteBufSize), config: config, }, nil @@ -282,10 +280,10 @@ func (st *DiskStorage) filepath(key string) (string, error) { pb.AppendString(st.path) pb.AppendString(key) - // If path is dir traversal, and traverses FURTHER - // than store root, this is an error - if util.CountDotdots(pb.StringPtr()) > st.dots { + // Check for dir traversal outside of root + if util.IsDirTraversal(st.path, pb.StringPtr()) { return "", ErrInvalidKey } + return pb.String(), nil } diff --git a/vendor/codeberg.org/gruf/go-store/storage/memory.go b/vendor/codeberg.org/gruf/go-store/storage/memory.go index e30aef571..be60fa464 100644 --- a/vendor/codeberg.org/gruf/go-store/storage/memory.go +++ b/vendor/codeberg.org/gruf/go-store/storage/memory.go @@ -2,7 +2,6 @@ package storage import ( "io" - "sync" "codeberg.org/gruf/go-bytes" "codeberg.org/gruf/go-store/util" @@ -12,14 +11,12 @@ import ( // pairs in a Go map in-memory. The map is protected by a mutex. type MemoryStorage struct { fs map[string][]byte - mu sync.Mutex } // OpenMemory opens a new MemoryStorage instance with internal map of 'size'. func OpenMemory(size int) *MemoryStorage { return &MemoryStorage{ fs: make(map[string][]byte, size), - mu: sync.Mutex{}, } } @@ -30,33 +27,19 @@ func (st *MemoryStorage) Clean() error { // ReadBytes implements Storage.ReadBytes(). func (st *MemoryStorage) ReadBytes(key string) ([]byte, error) { - // Safely check store - st.mu.Lock() b, ok := st.fs[key] - st.mu.Unlock() - - // Return early if not exist if !ok { return nil, ErrNotFound } - - // Create return copy return bytes.Copy(b), nil } // ReadStream implements Storage.ReadStream(). func (st *MemoryStorage) ReadStream(key string) (io.ReadCloser, error) { - // Safely check store - st.mu.Lock() b, ok := st.fs[key] - st.mu.Unlock() - - // Return early if not exist if !ok { return nil, ErrNotFound } - - // Create io.ReadCloser from 'b' copy b = bytes.Copy(b) r := bytes.NewReader(b) return util.NopReadCloser(r), nil @@ -64,68 +47,43 @@ func (st *MemoryStorage) ReadStream(key string) (io.ReadCloser, error) { // WriteBytes implements Storage.WriteBytes(). func (st *MemoryStorage) WriteBytes(key string, b []byte) error { - // Safely check store - st.mu.Lock() _, ok := st.fs[key] - - // Check for already exist if ok { - st.mu.Unlock() return ErrAlreadyExists } - - // Write + unlock st.fs[key] = bytes.Copy(b) - st.mu.Unlock() return nil } // WriteStream implements Storage.WriteStream(). func (st *MemoryStorage) WriteStream(key string, r io.Reader) error { - // Read all from reader b, err := io.ReadAll(r) if err != nil { return err } - - // Write to storage return st.WriteBytes(key, b) } // Stat implements Storage.Stat(). func (st *MemoryStorage) Stat(key string) (bool, error) { - st.mu.Lock() _, ok := st.fs[key] - st.mu.Unlock() return ok, nil } // Remove implements Storage.Remove(). func (st *MemoryStorage) Remove(key string) error { - // Safely check store - st.mu.Lock() _, ok := st.fs[key] - - // Check in store if !ok { - st.mu.Unlock() return ErrNotFound } - - // Delete + unlock delete(st.fs, key) - st.mu.Unlock() return nil } // WalkKeys implements Storage.WalkKeys(). func (st *MemoryStorage) WalkKeys(opts WalkKeysOptions) error { - // Safely walk storage keys - st.mu.Lock() for key := range st.fs { opts.WalkFn(entry(key)) } - st.mu.Unlock() - return nil } diff --git a/vendor/codeberg.org/gruf/go-store/util/fs.go b/vendor/codeberg.org/gruf/go-store/util/fs.go index fa6a9d2c4..93b37a261 100644 --- a/vendor/codeberg.org/gruf/go-store/util/fs.go +++ b/vendor/codeberg.org/gruf/go-store/util/fs.go @@ -9,14 +9,22 @@ import ( "codeberg.org/gruf/go-fastpath" ) -var dotdot = "../" +// IsDirTraversal will check if rootPlusPath is a dir traversal outside of root, +// assuming that both are cleaned and that rootPlusPath is path.Join(root, somePath) +func IsDirTraversal(root string, rootPlusPath string) bool { + switch { + // Root is $PWD, check for traversal out of + case root == ".": + return strings.HasPrefix(rootPlusPath, "../") -// CountDotdots returns the number of "dot-dots" (../) in a cleaned filesystem path -func CountDotdots(path string) int { - if !strings.HasSuffix(path, dotdot) { - return 0 + // The path MUST be prefixed by root + case !strings.HasPrefix(rootPlusPath, root): + return true + + // In all other cases, check not equal + default: + return len(root) == len(rootPlusPath) } - return strings.Count(path, dotdot) } // WalkDir traverses the dir tree of the supplied path, performing the supplied walkFn on each entry |