damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 58e2fb40ef651e32ed659f421e44e1fb19be8fe9
parent af7ea7024fd2ed55a516de24b58e7cd21555366c
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 22 Jul 2023 16:56:13 -0700

iter: make safer by using NdbNote instead of unsafe pointers

If we have an owned note, we could lose track of the lifetime and then
crash. Let's make sure we always have an NdbNote instead

Diffstat:
Mnostrdb/NdbNote.swift | 2+-
Mnostrdb/NdbTagElem.swift | 10+++++-----
Mnostrdb/NdbTagIterator.swift | 22+++++++++++++++++++---
Mnostrdb/NdbTagsIterator.swift | 14++++++++++----
4 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/nostrdb/NdbNote.swift b/nostrdb/NdbNote.swift @@ -34,7 +34,7 @@ struct NdbNote { } func tags() -> TagsSequence { - return .init(note: note) + return .init(note: self) } static func owned_from_json(json: String, bufsize: Int = 2 << 18) -> NdbNote? { diff --git a/nostrdb/NdbTagElem.swift b/nostrdb/NdbTagElem.swift @@ -8,22 +8,22 @@ import Foundation struct NdbTagElem { - private let note: UnsafeMutablePointer<ndb_note> + private let note: NdbNote private let tag: UnsafeMutablePointer<ndb_tag> let index: Int32 - init(note: UnsafeMutablePointer<ndb_note>, tag: UnsafeMutablePointer<ndb_tag>, index: Int32) { + init(note: NdbNote, tag: UnsafeMutablePointer<ndb_tag>, index: Int32) { self.note = note self.tag = tag self.index = index } - func matches_char(c: AsciiCharacter) -> Bool { - return ndb_tag_matches_char(note, tag, index, c.cchar) == 1 + func matches_char(_ c: AsciiCharacter) -> Bool { + return ndb_tag_matches_char(note.note, tag, index, c.cchar) == 1 } func string() -> String { - return String(cString: ndb_tag_str(note, tag, index), encoding: .utf8) ?? "" + return String(cString: ndb_tag_str(note.note, tag, index), encoding: .utf8) ?? "" } } diff --git a/nostrdb/NdbTagIterator.swift b/nostrdb/NdbTagIterator.swift @@ -8,9 +8,21 @@ import Foundation struct TagSequence: Sequence { - let note: UnsafeMutablePointer<ndb_note> + let note: NdbNote let tag: UnsafeMutablePointer<ndb_tag> + var count: UInt16 { + tag.pointee.count + } + + subscript(index: Int) -> NdbTagElem? { + if index >= tag.pointee.count { + return nil + } + + return NdbTagElem(note: note, tag: tag, index: Int32(index)) + } + func makeIterator() -> TagIterator { return TagIterator(note: note, tag: tag) } @@ -29,10 +41,14 @@ struct TagIterator: IteratorProtocol { } var index: Int32 - let note: UnsafeMutablePointer<ndb_note> + let note: NdbNote var tag: UnsafeMutablePointer<ndb_tag> - init(note: UnsafeMutablePointer<ndb_note>, tag: UnsafeMutablePointer<ndb_tag>) { + var count: UInt16 { + tag.pointee.count + } + + init(note: NdbNote, tag: UnsafeMutablePointer<ndb_tag>) { self.note = note self.tag = tag self.index = 0 diff --git a/nostrdb/NdbTagsIterator.swift b/nostrdb/NdbTagsIterator.swift @@ -12,11 +12,12 @@ struct TagsIterator: IteratorProtocol { var done: Bool var iter: ndb_iterator + var note: NdbNote mutating func next() -> TagSequence? { guard !done else { return nil } - let tag_seq = TagSequence(note: iter.note, tag: self.iter.tag) + let tag_seq = TagSequence(note: note, tag: self.iter.tag) let ok = ndb_tags_iterate_next(&self.iter) done = ok == 0 @@ -24,15 +25,20 @@ struct TagsIterator: IteratorProtocol { return tag_seq } - init(note: UnsafeMutablePointer<ndb_note>) { + var count: UInt16 { + return iter.tag.pointee.count + } + + init(note: NdbNote) { self.iter = ndb_iterator() - let res = ndb_tags_iterate_start(note, &self.iter) + let res = ndb_tags_iterate_start(note.note, &self.iter) self.done = res == 0 + self.note = note } } struct TagsSequence: Sequence { - let note: UnsafeMutablePointer<ndb_note> + let note: NdbNote func makeIterator() -> TagsIterator { return .init(note: note)