From f4c11bc2ffc1c6fd8ac3307d6054b88f3e1156d9 Mon Sep 17 00:00:00 2001 From: bbedward Date: Thu, 23 Apr 2026 09:28:26 -0400 Subject: [PATCH] clipboard: decode metadata only --- core/internal/server/clipboard/manager.go | 104 +++++++++++++++------- 1 file changed, 70 insertions(+), 34 deletions(-) diff --git a/core/internal/server/clipboard/manager.go b/core/internal/server/clipboard/manager.go index f5f528b8..91867a2a 100644 --- a/core/internal/server/clipboard/manager.go +++ b/core/internal/server/clipboard/manager.go @@ -212,9 +212,10 @@ func (m *Manager) setupDataDeviceSync() { } var offer any - if e.Id != nil { + switch { + case e.Id != nil: offer = e.Id - } else if e.OfferId != 0 { + case e.OfferId != 0: m.offerMutex.RLock() offer = m.offerRegistry[e.OfferId] m.offerMutex.RUnlock() @@ -224,10 +225,6 @@ func (m *Manager) setupDataDeviceSync() { wasOwner := m.isOwner m.ownerLock.Unlock() - if offer == nil { - return - } - if wasOwner { return } @@ -236,9 +233,11 @@ func (m *Manager) setupDataDeviceSync() { m.currentOffer = offer if prevOffer != nil && prevOffer != offer { - m.offerMutex.Lock() - delete(m.offerMimeTypes, prevOffer) - m.offerMutex.Unlock() + m.releaseOffer(prevOffer) + } + + if offer == nil { + return } m.offerMutex.RLock() @@ -292,6 +291,33 @@ func (m *Manager) setupDataDeviceSync() { log.Info("Data device setup complete") } +func (m *Manager) releaseOffer(offer any) { + if offer == nil { + return + } + typedOffer, ok := offer.(*ext_data_control.ExtDataControlOfferV1) + if !ok { + return + } + m.offerMutex.Lock() + delete(m.offerMimeTypes, offer) + delete(m.offerRegistry, typedOffer.ID()) + m.offerMutex.Unlock() + typedOffer.Destroy() +} + +func (m *Manager) releaseCurrentSource() { + if m.currentSource == nil { + return + } + source, ok := m.currentSource.(*ext_data_control.ExtDataControlSourceV1) + m.currentSource = nil + if !ok { + return + } + source.Destroy() +} + func (m *Manager) readAndStore(r *os.File, mimeType string) { defer r.Close() @@ -395,7 +421,7 @@ func (m *Manager) deduplicateInTx(b *bolt.Bucket, hash uint64) error { if extractHash(v) != hash { continue } - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err == nil && entry.Pinned { continue } @@ -413,7 +439,7 @@ func (m *Manager) trimLengthInTx(b *bolt.Bucket) error { c := b.Cursor() var count int for k, v := c.Last(); k != nil; k, v = c.Prev() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err == nil && entry.Pinned { continue } @@ -456,6 +482,14 @@ func encodeEntry(e Entry) ([]byte, error) { } func decodeEntry(data []byte) (Entry, error) { + return decodeEntryFields(data, true) +} + +func decodeEntryMeta(data []byte) (Entry, error) { + return decodeEntryFields(data, false) +} + +func decodeEntryFields(data []byte, withData bool) (Entry, error) { buf := bytes.NewReader(data) var e Entry @@ -463,8 +497,15 @@ func decodeEntry(data []byte) (Entry, error) { var dataLen uint32 binary.Read(buf, binary.BigEndian, &dataLen) - e.Data = make([]byte, dataLen) - buf.Read(e.Data) + switch { + case withData: + e.Data = make([]byte, dataLen) + buf.Read(e.Data) + default: + if _, err := buf.Seek(int64(dataLen), io.SeekCurrent); err != nil { + return e, err + } + } var mimeLen uint32 binary.Read(buf, binary.BigEndian, &mimeLen) @@ -668,14 +709,9 @@ func sizeStr(size int) string { func (m *Manager) updateState() { history := m.GetHistory() - for i := range history { - history[i].Data = nil - } - var current *Entry if len(history) > 0 { c := history[0] - c.Data = nil current = &c } @@ -750,7 +786,7 @@ func (m *Manager) GetHistory() []Entry { c := b.Cursor() for k, v := c.Last(); k != nil; k, v = c.Prev() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err != nil { continue } @@ -935,7 +971,7 @@ func (m *Manager) ClearHistory() { var toDelete [][]byte c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err != nil || !entry.Pinned { toDelete = append(toDelete, k) } @@ -958,7 +994,7 @@ func (m *Manager) ClearHistory() { if b != nil { c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { - entry, _ := decodeEntry(v) + entry, _ := decodeEntryMeta(v) if entry.Pinned { pinnedCount++ } @@ -1066,6 +1102,7 @@ func (m *Manager) SetClipboard(data []byte, mimeType string) error { m.ownerLock.Unlock() }) + m.releaseCurrentSource() m.currentSource = source m.sourceMutex.Lock() m.sourceMimeTypes = []string{mimeType} @@ -1145,9 +1182,11 @@ func (m *Manager) Close() { m.subscribers = make(map[string]chan State) m.subMutex.Unlock() - if m.currentSource != nil { - source := m.currentSource.(*ext_data_control.ExtDataControlSourceV1) - source.Destroy() + m.releaseCurrentSource() + + if m.currentOffer != nil { + m.releaseOffer(m.currentOffer) + m.currentOffer = nil } if m.dataDevice != nil { @@ -1191,11 +1230,10 @@ func (m *Manager) clearOldEntries(days int) error { var toDelete [][]byte c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err != nil { continue } - // Skip pinned entries if entry.Pinned { continue } @@ -1310,7 +1348,7 @@ func (m *Manager) Search(params SearchParams) SearchResult { c := b.Cursor() for k, v := c.Last(); k != nil; k, v = c.Prev() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err != nil { continue } @@ -1335,7 +1373,6 @@ func (m *Manager) Search(params SearchParams) SearchResult { continue } - entry.Data = nil all = append(all, entry) } return nil @@ -1510,7 +1547,7 @@ func (m *Manager) PinEntry(id uint64) error { } c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err != nil || !entry.Pinned { continue } @@ -1528,7 +1565,6 @@ func (m *Manager) PinEntry(id uint64) error { return nil } - // Check pinned count cfg := m.getConfig() pinnedCount := 0 if err := m.db.View(func(tx *bolt.Tx) error { @@ -1538,7 +1574,7 @@ func (m *Manager) PinEntry(id uint64) error { } c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err == nil && entry.Pinned { pinnedCount++ } @@ -1629,12 +1665,11 @@ func (m *Manager) GetPinnedEntries() []Entry { c := b.Cursor() for k, v := c.Last(); k != nil; k, v = c.Prev() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err != nil { continue } if entry.Pinned { - entry.Data = nil pinned = append(pinned, entry) } } @@ -1660,7 +1695,7 @@ func (m *Manager) GetPinnedCount() int { c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { - entry, err := decodeEntry(v) + entry, err := decodeEntryMeta(v) if err == nil && entry.Pinned { count++ } @@ -1779,6 +1814,7 @@ func (m *Manager) CopyFile(filePath string) error { m.ownerLock.Unlock() }) + m.releaseCurrentSource() m.currentSource = source m.ownerLock.Lock()