fix: harden talk silence timeout parsing (#39607) (thanks @danodoesdesign)

Co-authored-by: dano does design <dano.does.design@gmail.com>
This commit is contained in:
Peter Steinberger
2026-03-08 14:29:42 +00:00
parent 6ff7e8f42e
commit 0af3118d08
5 changed files with 38 additions and 18 deletions

View File

@@ -107,7 +107,9 @@ class TalkModeManager(
}
internal fun resolvedSilenceTimeoutMs(talk: JsonObject?): Long {
val timeout = talk?.get("silenceTimeoutMs").asDoubleOrNull() ?: return defaultSilenceTimeoutMs
val primitive = talk?.get("silenceTimeoutMs") as? JsonPrimitive ?: return defaultSilenceTimeoutMs
if (primitive.isString) return defaultSilenceTimeoutMs
val timeout = primitive.content.toDoubleOrNull() ?: return defaultSilenceTimeoutMs
if (timeout <= 0 || timeout % 1.0 != 0.0 || timeout > Long.MAX_VALUE.toDouble()) {
return defaultSilenceTimeoutMs
}

View File

@@ -73,4 +73,11 @@ class TalkModeConfigParsingTest {
assertEquals(700L, TalkModeManager.resolvedSilenceTimeoutMs(talk))
}
@Test
fun defaultsSilenceTimeoutMsWhenString() {
val talk = buildJsonObject { put("silenceTimeoutMs", "1500") }
assertEquals(700L, TalkModeManager.resolvedSilenceTimeoutMs(talk))
}
}

View File

@@ -98,7 +98,7 @@ final class TalkModeManager: NSObject {
private var gateway: GatewayNodeSession?
private var gatewayConnected = false
private var silenceWindow: TimeInterval = TimeInterval(Self.defaultSilenceTimeoutMs) / 1000
private var silenceWindow: TimeInterval = TimeInterval(TalkModeManager.defaultSilenceTimeoutMs) / 1000
private var lastAudioActivity: Date?
private var noiseFloorSamples: [Double] = []
private var noiseFloor: Double?
@@ -2010,6 +2010,9 @@ extension TalkModeManager {
where timeout > 0 && timeout.rounded(.towardZero) == timeout && timeout <= Double(Int.max):
return Int(timeout)
case let timeout as NSNumber:
if CFGetTypeID(timeout) == CFBooleanGetTypeID() {
return Self.defaultSilenceTimeoutMs
}
let value = timeout.doubleValue
if value > 0 && value.rounded(.towardZero) == value && value <= Double(Int.max) {
return Int(value)

View File

@@ -67,4 +67,12 @@ import Testing
#expect(TalkModeManager.resolvedSilenceTimeoutMs(talk) == 900)
}
@Test func defaultsSilenceTimeoutMsWhenBool() {
let talk: [String: Any] = [
"silenceTimeoutMs": true,
]
#expect(TalkModeManager.resolvedSilenceTimeoutMs(talk) == 900)
}
}