Skip to content

Commit af610cd

Browse files
sl0thentr0pyclaude
andauthored
fix(stacktrace): stop leaking internal frame state into event payload (#2962)
Interface#to_h serializes every instance variable, so helper ivars stored on StacktraceInterface::Frame leaked into the event payload. The FilenameCache change (#2904) made this worse by serializing "#<Sentry::FilenameCache:0x...>" — a memory address that differs on every run — into every frame. Pass filename_cache/strip_backtrace_load_path through the constructor instead of storing them as ivars, so they never reach to_h. This also drops the pre-existing project_root/strip_backtrace_load_path leaks. All real frame fields are unchanged. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent a1f02d6 commit af610cd

2 files changed

Lines changed: 8 additions & 8 deletions

File tree

sentry-ruby/lib/sentry/interfaces/stacktrace.rb

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,18 @@ class Frame < Interface
2828
:lineno, :module, :pre_context, :post_context, :vars
2929

3030
def initialize(project_root, line, strip_backtrace_load_path = true, filename_cache: nil)
31-
@strip_backtrace_load_path = strip_backtrace_load_path
32-
@filename_cache = filename_cache
33-
3431
@abs_path = line.file
3532
@function = line.method if line.method
3633
@lineno = line.number
3734
@in_app = line.in_app
3835
@module = line.module_name if line.module_name
39-
@filename = compute_filename
36+
@filename = filename_cache&.compute_filename(@abs_path, @in_app, strip_backtrace_load_path)
4037
end
4138

4239
def to_s
4340
"#{@filename}:#{@lineno}"
4441
end
4542

46-
def compute_filename
47-
@filename_cache&.compute_filename(abs_path, in_app, @strip_backtrace_load_path)
48-
end
49-
5043
def set_context(linecache, context_lines)
5144
return unless abs_path
5245

sentry-ruby/spec/sentry/interfaces/stacktrace_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
expect(second_frame.lineno).to eq(5)
3131
end
3232

33+
it "does not leak internal state into the serialized frame payload" do
34+
frame = Sentry::StacktraceInterface::Frame.new(configuration.project_root, lines.last, true, filename_cache: filename_cache)
35+
36+
expect(frame.to_h.keys).to contain_exactly(:abs_path, :function, :lineno, :in_app, :filename)
37+
expect(frame.to_h).not_to include(:project_root, :strip_backtrace_load_path, :filename_cache)
38+
end
39+
3340
it "does not strip load path when strip_backtrace_load_path is false" do
3441
first_frame = Sentry::StacktraceInterface::Frame.new(configuration.project_root, lines.first, false, filename_cache: filename_cache)
3542
expect(first_frame.filename).to eq(first_frame.abs_path)

0 commit comments

Comments
 (0)