Skip to content

Commit a13665c

Browse files
committed
fix(redis): fix deinit use-after-free, SELECT cache sync, and glob escaping
- Restore async dispatch in deinit to prevent use-after-free when commands are in-flight on the serial queue - Use conn.selectDatabase() for SELECT command in query editor so _currentDatabase is updated and SCAN cache key stays correct - Quote keys with spaces in buildExplainQuery DEBUG OBJECT command - Escape ] in escapeGlobChars for correct SCAN MATCH patterns
1 parent 8b894d1 commit a13665c

3 files changed

Lines changed: 14 additions & 5 deletions

File tree

Plugins/RedisDriverPlugin/RedisPluginConnection.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,14 @@ final class RedisPluginConnection: @unchecked Sendable {
173173
sslContext = nil
174174
stateLock.unlock()
175175

176-
if let handle { redisFree(handle) }
177-
if let ssl { redisFreeSSLContext(ssl) }
176+
// Dispatch cleanup to the serial queue to ensure in-flight commands complete first
177+
if handle != nil || ssl != nil {
178+
let cleanupQueue = queue
179+
cleanupQueue.async {
180+
if let handle { redisFree(handle) }
181+
if let ssl { redisFreeSSLContext(ssl) }
182+
}
183+
}
178184
#endif
179185
}
180186

Plugins/RedisDriverPlugin/RedisPluginDriver.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ final class RedisPluginDriver: PluginDatabaseDriver, @unchecked Sendable {
440440
}()
441441

442442
guard let key else { return nil }
443-
return "DEBUG OBJECT \(key)"
443+
let quoted = key.contains(" ") || key.contains("\"") ? "\"\(key.replacingOccurrences(of: "\"", with: "\\\""))\"" : key
444+
return "DEBUG OBJECT \(quoted)"
444445
}
445446

446447
// MARK: - View Templates
@@ -1016,7 +1017,9 @@ private extension RedisPluginDriver {
10161017
return buildStatusResult("OK", startTime: startTime)
10171018

10181019
case .select(let database):
1019-
_ = try await conn.executeCommand(["SELECT", String(database)])
1020+
try await conn.selectDatabase(database)
1021+
cachedScanPattern = nil
1022+
cachedScanKeys = nil
10201023
return buildStatusResult("OK", startTime: startTime)
10211024

10221025
case .configGet(let parameter):

Plugins/RedisDriverPlugin/RedisQueryBuilder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ struct RedisQueryBuilder {
104104
var result = ""
105105
for char in str {
106106
switch char {
107-
case "*", "?", "[":
107+
case "*", "?", "[", "]":
108108
result.append("\\")
109109
result.append(char)
110110
case "\\":

0 commit comments

Comments
 (0)