diff --git a/sentry-ruby/lib/sentry/propagation_context.rb b/sentry-ruby/lib/sentry/propagation_context.rb index 34b314cc6..86c5b3f22 100644 --- a/sentry-ruby/lib/sentry/propagation_context.rb +++ b/sentry-ruby/lib/sentry/propagation_context.rb @@ -8,11 +8,9 @@ module Sentry class PropagationContext SENTRY_TRACE_REGEXP = Regexp.new( - "^[ \t]*" + # whitespace - "([0-9a-f]{32})?" + # trace_id + "\\A([0-9a-f]{32})?" + # trace_id "-?([0-9a-f]{16})?" + # span_id - "-?([01])?" + # sampled - "[ \t]*$" # whitespace + "-?([01])?\\z" # sampled ) # An uuid that can be used to identify a trace. @@ -43,7 +41,10 @@ class PropagationContext # @param sentry_trace [String] the sentry-trace header value from the previous transaction. # @return [Array, nil] def self.extract_sentry_trace(sentry_trace) - match = SENTRY_TRACE_REGEXP.match(sentry_trace) + value = sentry_trace.to_s.strip + return if value.empty? + + match = SENTRY_TRACE_REGEXP.match(value) return if match.nil? trace_id, parent_span_id, sampled_flag = match[1..3] diff --git a/sentry-ruby/spec/sentry/propagation_context_spec.rb b/sentry-ruby/spec/sentry/propagation_context_spec.rb index cb2165f02..418360de1 100644 --- a/sentry-ruby/spec/sentry/propagation_context_spec.rb +++ b/sentry-ruby/spec/sentry/propagation_context_spec.rb @@ -132,4 +132,41 @@ expect(subject.get_dynamic_sampling_context).to eq(subject.get_baggage.dynamic_sampling_context) end end + + describe ".extract_sentry_trace" do + it "extracts valid sentry-trace without whitespace" do + sentry_trace = "771a43a4192642f0b136d5159a501700-7c51afd529da4a2a-1" + result = described_class.extract_sentry_trace(sentry_trace) + + expect(result).to eq(["771a43a4192642f0b136d5159a501700", "7c51afd529da4a2a", true]) + end + + it "extracts valid sentry-trace with leading and trailing whitespace" do + sentry_trace = " \t771a43a4192642f0b136d5159a501700-7c51afd529da4a2a-1\t " + result = described_class.extract_sentry_trace(sentry_trace) + + expect(result).to eq(["771a43a4192642f0b136d5159a501700", "7c51afd529da4a2a", true]) + end + + it "extracts sentry-trace without sampled flag" do + sentry_trace = "771a43a4192642f0b136d5159a501700-7c51afd529da4a2a" + result = described_class.extract_sentry_trace(sentry_trace) + + expect(result).to eq(["771a43a4192642f0b136d5159a501700", "7c51afd529da4a2a", nil]) + end + + it "returns nil for invalid sentry-trace" do + expect(described_class.extract_sentry_trace("invalid")).to be_nil + expect(described_class.extract_sentry_trace("000-000-0")).to be_nil + expect(described_class.extract_sentry_trace("")).to be_nil + end + + it "allows whitespace" do + whitespace = " \t \t \t \t " + sentry_trace = "#{whitespace}771a43a4192642f0b136d5159a501700-7c51afd529da4a2a-1#{whitespace}" + result = described_class.extract_sentry_trace(sentry_trace) + + expect(result).to eq(["771a43a4192642f0b136d5159a501700", "7c51afd529da4a2a", true]) + end + end end