Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LaunchDarkly/LaunchDarkly/Models/Context/LDContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public struct LDContext: Encodable, Equatable {
for key in optionalAttributeNames {
if let value = context.getTopLevelAddressableAttributeSingleKind(key) {
if redactAll {
redactedAttributes.append(key)
redactedAttributes.append(Reference(literal: key).raw())
continue
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ extension LDContext {
else { continue }

if redactAll {
redaction.redactedAttributes.append(name)
redaction.redactedAttributes.append(Reference(literal: name).raw())
continue
}

Expand Down
13 changes: 11 additions & 2 deletions LaunchDarkly/LaunchDarklyTests/EventJSONWriterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -432,11 +432,14 @@ final class EventJSONWriterTests: XCTestCase {
}

/// An attribute name is a literal name, not an attribute reference: `/foo` names an attribute called `/foo`, not the
/// path `foo`. Only private attributes are references, and they match the name as one component.
/// path `foo`. Private attributes and `redactedAttributes` are references, so a name starting with a slash is
/// listed as the one-component path that refers to it, `/~1foo`.
func testAttributeNamesStartingWithASlashAreWrittenAndRedactedByName() throws {
var builder = LDContextBuilder(key: "user-key")
_ = builder.trySetValue("/foo", "bar")
_ = builder.trySetValue("/secret", "hidden")
_ = builder.trySetValue("/a~b/c", true)
_ = builder.trySetValue("x/y", 2)
_ = builder.trySetValue("plain", 1)
builder.addPrivateAttribute(Reference("/~1secret"))
builder.addPrivateAttribute(Reference("/foo"))
Expand Down Expand Up @@ -465,14 +468,20 @@ final class EventJSONWriterTests: XCTestCase {
if allAttributesPrivate {
XCTAssertNil(written["/foo"], label)
XCTAssertNil(written["plain"], label)
XCTAssertEqual(Set(redacted(written)), ["/foo", "/secret", "plain"], label)
XCTAssertEqual(Set(redacted(written)), ["/~1foo", "/~1secret", "/~1a~0b~1c", "x/y", "plain"], label)
} else {
// `Reference("/foo")` is the path `foo`, which names no attribute here.
XCTAssertEqual(written["/foo"] as? String, "bar", label)
XCTAssertEqual(written["plain"] as? Int, 1, label)
XCTAssertEqual(redacted(written), ["/~1secret"], label)
}
XCTAssertNil(written["/secret"], label)
// Each entry, parsed back as a reference, refers to an attribute that was left out.
for entry in redacted(written) {
let reference = Reference(entry)
XCTAssertTrue(reference.isValid(), "\(label): \(entry)")
XCTAssertNotNil(context.getValue(reference), "\(label): \(entry)")
}
}
}

Expand Down
Loading