Skip to content

Commit f9945dc

Browse files
kgilpinclaude
andcommitted
fix: Use raw string values instead of repr() for str types in display_string
When APPMAP_DISPLAY_PARAMS=true, repr() wraps string values in quotes (e.g. 'my-api-key'), which breaks the scanner's secret-in-log substring matching. By using the raw string value directly for str types, the recorded value matches what appears in log messages, enabling proper secret leak detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1291051 commit f9945dc

13 files changed

Lines changed: 70 additions & 66 deletions

_appmap/event.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def display_string(val, has_labels=False):
6161
value = None
6262
if _should_display(has_labels):
6363
try:
64-
value = repr(val)
64+
value = val if isinstance(val, str) else repr(val)
6565
except Exception: # pylint: disable=broad-except
6666
pass
6767

_appmap/test/data/expected.appmap.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
{
2424
"return_value": {
2525
"class": "builtins.str",
26-
"value": "'ExampleClass.static_method\\n...\\n'"
26+
"value": "ExampleClass.static_method\n...\n"
2727
},
2828
"parent_id": 1,
2929
"id": 2,
@@ -49,7 +49,7 @@
4949
{
5050
"return_value": {
5151
"class": "builtins.str",
52-
"value": "'ClassMethodMixin#class_method, cls ExampleClass'"
52+
"value": "ClassMethodMixin#class_method, cls ExampleClass"
5353
},
5454
"parent_id": 3,
5555
"id": 4,
@@ -75,7 +75,7 @@
7575
{
7676
"return_value": {
7777
"class": "builtins.str",
78-
"value": "'Super#instance_method'"
78+
"value": "Super#instance_method"
7979
},
8080
"parent_id": 5,
8181
"id": 6,
@@ -127,7 +127,7 @@
127127
"name": "data",
128128
"kind": "req",
129129
"class": "builtins.str",
130-
"value": "'ExampleClass.call_yaml'"
130+
"value": "ExampleClass.call_yaml"
131131
}
132132
],
133133
"id": 10,
@@ -144,7 +144,7 @@
144144
"name": "data",
145145
"kind": "req",
146146
"class": "builtins.str",
147-
"value": "'ExampleClass.call_yaml'"
147+
"value": "ExampleClass.call_yaml"
148148
},
149149
{
150150
"name": "stream",
@@ -176,7 +176,7 @@
176176
{
177177
"return_value": {
178178
"class": "builtins.str",
179-
"value": "'ExampleClass.call_yaml\\n...\\n'"
179+
"value": "ExampleClass.call_yaml\n...\n"
180180
},
181181
"parent_id": 11,
182182
"id": 12,
@@ -190,7 +190,7 @@
190190
"name": "data",
191191
"kind": "req",
192192
"class": "builtins.str",
193-
"value": "'ExampleClass.call_yaml'"
193+
"value": "ExampleClass.call_yaml"
194194
},
195195
{
196196
"name": "stream",
@@ -222,7 +222,7 @@
222222
{
223223
"return_value": {
224224
"class": "builtins.str",
225-
"value": "'ExampleClass.call_yaml\\n...\\n'"
225+
"value": "ExampleClass.call_yaml\n...\n"
226226
},
227227
"parent_id": 13,
228228
"id": 14,
@@ -334,4 +334,4 @@
334334
]
335335
}
336336
]
337-
}
337+
}

_appmap/test/data/pytest/expected/pytest-numpy1-no-test-cases.appmap.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
{
5757
"return_value": {
5858
"class": "builtins.str",
59-
"value": "'Hello'"
59+
"value": "Hello"
6060
},
6161
"parent_id": 2,
6262
"id": 3,
@@ -83,7 +83,7 @@
8383
{
8484
"return_value": {
8585
"class": "builtins.str",
86-
"value": "'world!'"
86+
"value": "world!"
8787
},
8888
"parent_id": 4,
8989
"id": 5,
@@ -93,7 +93,7 @@
9393
{
9494
"return_value": {
9595
"class": "builtins.str",
96-
"value": "'Hello world!'"
96+
"value": "Hello world!"
9797
},
9898
"parent_id": 1,
9999
"id": 6,
@@ -239,4 +239,4 @@
239239
]
240240
}
241241
]
242-
}
242+
}

_appmap/test/data/pytest/expected/pytest-numpy1.appmap.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
},
6767
{
6868
"return_value": {
69-
"value": "'Hello'",
69+
"value": "Hello",
7070
"class": "builtins.str"
7171
},
7272
"parent_id": 3,
@@ -93,7 +93,7 @@
9393
},
9494
{
9595
"return_value": {
96-
"value": "'world!'",
96+
"value": "world!",
9797
"class": "builtins.str"
9898
},
9999
"parent_id": 5,
@@ -103,7 +103,7 @@
103103
},
104104
{
105105
"return_value": {
106-
"value": "'Hello world!'",
106+
"value": "Hello world!",
107107
"class": "builtins.str"
108108
},
109109
"parent_id": 2,
@@ -278,4 +278,4 @@
278278
]
279279
}
280280
]
281-
}
281+
}

_appmap/test/data/pytest/expected/pytest-numpy2-no-test-cases.appmap.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
{
5757
"return_value": {
5858
"class": "builtins.str",
59-
"value": "'Hello'"
59+
"value": "Hello"
6060
},
6161
"parent_id": 2,
6262
"id": 3,
@@ -83,7 +83,7 @@
8383
{
8484
"return_value": {
8585
"class": "builtins.str",
86-
"value": "'world!'"
86+
"value": "world!"
8787
},
8888
"parent_id": 4,
8989
"id": 5,
@@ -93,7 +93,7 @@
9393
{
9494
"return_value": {
9595
"class": "builtins.str",
96-
"value": "'Hello world!'"
96+
"value": "Hello world!"
9797
},
9898
"parent_id": 1,
9999
"id": 6,
@@ -239,4 +239,4 @@
239239
]
240240
}
241241
]
242-
}
242+
}

_appmap/test/data/pytest/expected/pytest-numpy2.appmap.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
},
6767
{
6868
"return_value": {
69-
"value": "'Hello'",
69+
"value": "Hello",
7070
"class": "builtins.str"
7171
},
7272
"parent_id": 3,
@@ -93,7 +93,7 @@
9393
},
9494
{
9595
"return_value": {
96-
"value": "'world!'",
96+
"value": "world!",
9797
"class": "builtins.str"
9898
},
9999
"parent_id": 5,
@@ -103,7 +103,7 @@
103103
},
104104
{
105105
"return_value": {
106-
"value": "'Hello world!'",
106+
"value": "Hello world!",
107107
"class": "builtins.str"
108108
},
109109
"parent_id": 2,
@@ -278,4 +278,4 @@
278278
]
279279
}
280280
]
281-
}
281+
}

_appmap/test/data/unittest/expected/pytest.appmap.json

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,14 @@
5353
"class": "simple.Simple",
5454
"value": "<simple.Simple object at 0xabcdef>"
5555
},
56-
"parameters": [{
57-
"class": "builtins.str",
58-
"kind": "req",
59-
"name": "bang",
60-
"value": "'!'"
61-
}],
56+
"parameters": [
57+
{
58+
"class": "builtins.str",
59+
"kind": "req",
60+
"name": "bang",
61+
"value": "!"
62+
}
63+
],
6264
"id": 2,
6365
"event": "call",
6466
"thread_id": 1
@@ -83,7 +85,7 @@
8385
{
8486
"return_value": {
8587
"class": "builtins.str",
86-
"value": "'Hello'"
88+
"value": "Hello"
8789
},
8890
"parent_id": 3,
8991
"id": 4,
@@ -110,7 +112,7 @@
110112
{
111113
"return_value": {
112114
"class": "builtins.str",
113-
"value": "'world'"
115+
"value": "world"
114116
},
115117
"parent_id": 5,
116118
"id": 6,
@@ -120,7 +122,7 @@
120122
{
121123
"return_value": {
122124
"class": "builtins.str",
123-
"value": "'Hello world!'"
125+
"value": "Hello world!"
124126
},
125127
"parent_id": 2,
126128
"id": 7,

_appmap/test/data/unittest/expected/unittest-no-test-cases.appmap.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"parameters": [
3636
{
3737
"kind": "req",
38-
"value": "'!'",
38+
"value": "!",
3939
"name": "bang",
4040
"class": "builtins.str"
4141
}
@@ -67,7 +67,7 @@
6767
},
6868
{
6969
"return_value": {
70-
"value": "'Hello'",
70+
"value": "Hello",
7171
"class": "builtins.str"
7272
},
7373
"parent_id": 2,
@@ -94,7 +94,7 @@
9494
},
9595
{
9696
"return_value": {
97-
"value": "'world'",
97+
"value": "world",
9898
"class": "builtins.str"
9999
},
100100
"parent_id": 4,
@@ -104,7 +104,7 @@
104104
},
105105
{
106106
"return_value": {
107-
"value": "'Hello world!'",
107+
"value": "Hello world!",
108108
"class": "builtins.str"
109109
},
110110
"parent_id": 1,
@@ -145,4 +145,4 @@
145145
]
146146
}
147147
]
148-
}
148+
}

_appmap/test/data/unittest/expected/unittest.appmap.json

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,14 @@
5353
"class": "simple.Simple",
5454
"value": "<simple.Simple object at 0xabcdef>"
5555
},
56-
"parameters": [{
57-
"class": "builtins.str",
58-
"kind": "req",
59-
"name": "bang",
60-
"value": "'!'"
61-
}],
56+
"parameters": [
57+
{
58+
"class": "builtins.str",
59+
"kind": "req",
60+
"name": "bang",
61+
"value": "!"
62+
}
63+
],
6264
"id": 2,
6365
"event": "call",
6466
"thread_id": 1
@@ -83,7 +85,7 @@
8385
{
8486
"return_value": {
8587
"class": "builtins.str",
86-
"value": "'Hello'"
88+
"value": "Hello"
8789
},
8890
"parent_id": 3,
8991
"id": 4,
@@ -110,7 +112,7 @@
110112
{
111113
"return_value": {
112114
"class": "builtins.str",
113-
"value": "'world'"
115+
"value": "world"
114116
},
115117
"parent_id": 5,
116118
"id": 6,
@@ -120,7 +122,7 @@
120122
{
121123
"return_value": {
122124
"class": "builtins.str",
123-
"value": "'Hello world!'"
125+
"value": "Hello world!"
124126
},
125127
"parent_id": 2,
126128
"id": 7,

_appmap/test/test_events.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,11 @@ def test_labeled_params_displayed_by_default(self):
129129

130130
assert result == "hello"
131131
call_event = r.events[0]
132-
# Parameter value should be the repr, not the opaque object string
133-
assert call_event.parameters[0]["value"] == "'hello'"
132+
# Parameter value should be the raw string, not repr-quoted
133+
assert call_event.parameters[0]["value"] == "hello"
134134
# Return value should also be displayed
135135
return_event = r.events[1]
136-
assert return_event.return_value["value"] == "'hello'"
136+
assert return_event.return_value["value"] == "hello"
137137

138138
@pytest.mark.appmap_enabled(env={"APPMAP_DISPLAY_PARAMS": "false", "APPMAP_DISPLAY_LABELED_PARAMS": "false"})
139139
def test_labeled_params_not_displayed_when_disabled(self):

0 commit comments

Comments
 (0)