Skip to content

Commit 165fc6d

Browse files
authored
Merge pull request #1719 from ahoppen/ahoppen/5.9/memory-corruption
[5.9] Fix two memory corruption bugs in SwiftSyntax
2 parents 56c4f8b + d1db933 commit 165fc6d

File tree

10 files changed

+1707
-1694
lines changed

10 files changed

+1707
-1694
lines changed

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxNodesFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ func syntaxNode(emitKind: String) -> SourceFileSyntax {
221221
AccessorDeclSyntax(
222222
"""
223223
set(value) {
224-
self = \(raw: node.name)(data.replacingChild(at: \(raw: index), with: value\(raw: child.isOptional ? "?" : "").raw, arena: SyntaxArena()))
224+
self = \(raw: node.name)(data.replacingChild(at: \(raw: index), with: value\(raw: child.isOptional ? "?" : "").data, arena: SyntaxArena()))
225225
}
226226
"""
227227
)

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxRewriterFile.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,9 @@ let syntaxRewriterFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
342342
/// a parent if `node` had one.
343343
public func rewrite(_ node: Syntax) -> Syntax {
344344
let rewritten = self.visit(node)
345-
let arena = SyntaxArena()
346-
return Syntax(node.data.replacingSelf(rewritten.raw, arena: arena))
345+
return withExtendedLifetime(rewritten) {
346+
return Syntax(node.data.replacingSelf(rewritten.raw, arena: rewritten.raw.arena))
347+
}
347348
}
348349
"""
349350
)

Sources/SwiftSyntax/SyntaxData.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,10 @@ struct SyntaxData {
311311
let newParent = Syntax(parentData)
312312
return SyntaxData(absoluteRaw.replacingSelf(newRaw, newRootId: parentData.nodeId.rootId), parent: newParent)
313313
} else {
314-
// Otherwise, we're already the root, so return the new root data.
315-
return .forRoot(newRaw)
314+
return withExtendedLifetime(arena) {
315+
// Otherwise, we're already the root, so return the new root data.
316+
return .forRoot(newRaw)
317+
}
316318
}
317319
}
318320

@@ -332,6 +334,15 @@ struct SyntaxData {
332334
return replacingSelf(newRaw, arena: arena)
333335
}
334336

337+
/// Identical to `replacingChild(at: Int, with: RawSyntax?, arena: SyntaxArena)`
338+
/// that ensures that the arena of`newChild` doesn’t get de-allocated before
339+
/// `newChild` has been addded to the result.
340+
func replacingChild(at index: Int, with newChild: SyntaxData?, arena: SyntaxArena) -> SyntaxData {
341+
return withExtendedLifetime(newChild) {
342+
return replacingChild(at: index, with: newChild?.raw, arena: arena)
343+
}
344+
}
345+
335346
func withLeadingTrivia(_ leadingTrivia: Trivia, arena: SyntaxArena) -> SyntaxData {
336347
if let raw = raw.withLeadingTrivia(leadingTrivia, arena: arena) {
337348
return replacingSelf(raw, arena: arena)

Sources/SwiftSyntax/generated/SyntaxRewriter.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6996,7 +6996,8 @@ open class SyntaxRewriter {
69966996
/// a parent if `node` had one.
69976997
public func rewrite(_ node: Syntax) -> Syntax {
69986998
let rewritten = self.visit(node)
6999-
let arena = SyntaxArena()
7000-
return Syntax(node.data.replacingSelf(rewritten.raw, arena: arena))
6999+
return withExtendedLifetime(rewritten) {
7000+
return Syntax(node.data.replacingSelf(rewritten.raw, arena: rewritten.raw.arena))
7001+
}
70017002
}
70027003
}

0 commit comments

Comments
 (0)