We fixed a memory leak that existed for a long time, when we merged #22. Unfortunately, this introduced a new issue: When you create a document, we now mark it as managed. When you then reference a child node of the document and no longer keep a reference to the document itself, we will free the node for the document: https://github.com/SwiftDocOrg/CommonMark/blob/main/Sources/CommonMark/Nodes/Node.swift#L35 But this also frees all the child nodes and we suddenly have a use after free when we still have a reference to any child.
Minimal test case to reproduce:
func testCrashingChild() throws {
var heading: Heading?
try autoreleasepool {
var document: Document? = try Document(Fixtures.udhr)
heading = document!.children.first! as? Heading
document = nil
}
// Will crash because of use after free.
XCTAssertEqual("# [Universal Declaration of Human Rights][udhr]", heading?.render(format: .commonmark))
}
Before, this was not happening, because our document node was always leaking, therefore "preventing" this crash 😄.
I'd say that this is a very common use case of this library. E.g. when you try to upgrade SwiftMarkup to use CommonMark version 0.5.0, then you will run into this crash.
I'd happy to provide a fix for this, but I think we should discuss the approach first. If I'm not mistaken, this is somehow a design flaw in the parent to child relation and a simple managed flag is not enough to represent the relationship.