Skip to content

Commit 9a98d94

Browse files
Merge pull request #2740 from DataDog/simaoseica/RUM-15005/c-string-conversion
RUM-15005: Fix context C-string conversion in KSCrash injection
2 parents f126016 + e1eedf8 commit 9a98d94

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- [FEATURE] Add OOB scroll and swipe action tracking. See [#2717][]
44
- [IMPROVEMENT] Rename `DDRUMErrorEventErrorMeta` to `DDRUMErrorEventErrorMetaInfo`, add support of custom Objective-C runtime names for generated RUM models. See [#2705][]
55
- [FEATURE] Add `trackResourceHeaders` configuration to capture HTTP request and response headers in RUM Resource events. See [#2721][]
6+
- [FIX] Fix crash context C-string conversion in KSCrash injection. See [#2740][]
67

78
# 3.7.0 / 18-02-2026
89

@@ -1064,6 +1065,7 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
10641065
[#2705]: https://github.com/DataDog/dd-sdk-ios/pull/2705
10651066
[#2721]: https://github.com/DataDog/dd-sdk-ios/pull/2721
10661067
[#2717]: https://github.com/DataDog/dd-sdk-ios/pull/2717
1068+
[#2740]: https://github.com/DataDog/dd-sdk-ios/pull/2740
10671069

10681070
[@00fa9a]: https://github.com/00FA9A
10691071
[@britton-earnin]: https://github.com/Britton-Earnin

DatadogCrashReporting/Sources/KSCrashIntegration/KSCrashBacktrace.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ internal struct KSCrashBacktrace: BacktraceReporting {
116116
private func getThreadName(pthread: pthread_t) -> String? {
117117
var buffer = [CChar](repeating: 0, count: 256)
118118
guard pthread_getname_np(pthread, &buffer, buffer.count) == KERN_SUCCESS, buffer[0] != 0 else {
119-
telemetry.error("Failed to get pthread name")
120-
return nil // fails or empty
119+
return nil // Failed to get pthread name
121120
}
122121
return String(cString: buffer)
123122
}

DatadogCrashReporting/Sources/KSCrashIntegration/KSCrashPlugin.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ internal class KSCrashPlugin: NSObject, CrashReportingPlugin {
8585
}
8686

8787
func inject(context: Data) {
88-
context.withUnsafeBytes {
89-
let c_char = $0.bindMemory(to: CChar.self).baseAddress
90-
kscrash_setUserInfoJSON(c_char)
88+
let contextString = String(decoding: context, as: UTF8.self)
89+
contextString.withCString {
90+
kscrash_setUserInfoJSON($0)
9191
}
9292
}
9393

DatadogCrashReporting/Tests/KSCrashIntegration/KSCrashPluginTests.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import XCTest
88
@testable import DatadogCrashReporting
99
import KSCrashRecording
1010

11-
class KSCrashPluginTests: XCTestCase {
11+
final class KSCrashPluginTests: XCTestCase {
1212
// MARK: - Configuration Tests
1313

1414
func testConfiguration() throws {
@@ -20,4 +20,33 @@ class KSCrashPluginTests: XCTestCase {
2020
XCTAssertEqual(config.reportStoreConfiguration.maxReportCount, 1)
2121
XCTAssertEqual(config.reportStoreConfiguration.reportCleanupPolicy, .never)
2222
}
23+
24+
func testCStringFromContextAppendsTrailingNullTerminator() {
25+
// Given
26+
let context = Data("{\"context\":\"value\"}".utf8)
27+
28+
// When
29+
let cString = cStringBytesFrom(context: context)
30+
31+
// Then
32+
XCTAssertEqual(cString.dropLast(), context[...])
33+
XCTAssertEqual(cString.last, 0)
34+
}
35+
36+
func testCStringFromContextPreservesExplicitTrailingNullCharacter() {
37+
// Given
38+
let context = Data([123, 125, 0])
39+
40+
// When
41+
let cString = cStringBytesFrom(context: context)
42+
43+
// Then
44+
XCTAssertEqual(cString, Data([123, 125, 0, 0]))
45+
}
46+
47+
/// Rebuilds the exact C-string bytes (`utf8` payload + trailing `\0`) used by `inject(context:)`.
48+
private func cStringBytesFrom(context: Data) -> Data {
49+
let contextString = String(decoding: context, as: UTF8.self)
50+
return Data(contextString.utf8CString.map(UInt8.init(bitPattern:)))
51+
}
2352
}

0 commit comments

Comments
 (0)