From 58e2fb40ef651e32ed659f421e44e1fb19be8fe9 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Sat, 22 Jul 2023 16:56:13 -0700 Subject: [PATCH] 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 --- nostrdb/NdbNote.swift | 2 +- nostrdb/NdbTagElem.swift | 10 +++++----- nostrdb/NdbTagIterator.swift | 22 +++++++++++++++++++--- nostrdb/NdbTagsIterator.swift | 14 ++++++++++---- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/nostrdb/NdbNote.swift b/nostrdb/NdbNote.swift index f594d074..08bba2ea 100644 --- 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 index 0356b505..8a1dcf37 100644 --- a/nostrdb/NdbTagElem.swift +++ b/nostrdb/NdbTagElem.swift @@ -8,22 +8,22 @@ import Foundation struct NdbTagElem { - private let note: UnsafeMutablePointer + private let note: NdbNote private let tag: UnsafeMutablePointer let index: Int32 - init(note: UnsafeMutablePointer, tag: UnsafeMutablePointer, index: Int32) { + init(note: NdbNote, tag: UnsafeMutablePointer, 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 index 7fe0c58c..795c698a 100644 --- a/nostrdb/NdbTagIterator.swift +++ b/nostrdb/NdbTagIterator.swift @@ -8,9 +8,21 @@ import Foundation struct TagSequence: Sequence { - let note: UnsafeMutablePointer + let note: NdbNote let tag: UnsafeMutablePointer + 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 + let note: NdbNote var tag: UnsafeMutablePointer - init(note: UnsafeMutablePointer, tag: UnsafeMutablePointer) { + var count: UInt16 { + tag.pointee.count + } + + init(note: NdbNote, tag: UnsafeMutablePointer) { self.note = note self.tag = tag self.index = 0 diff --git a/nostrdb/NdbTagsIterator.swift b/nostrdb/NdbTagsIterator.swift index 6ba2fa1c..00ada3a6 100644 --- 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) { + 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 + let note: NdbNote func makeIterator() -> TagsIterator { return .init(note: note)