Skip to content

Commit e1e7b57

Browse files
nficanocursoragent
andcommitted
fix: use strict Base64 decoding for result_chunk (§8.4) (#77)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 44a8e35 commit e1e7b57

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

lib/arcp/job/event_body/result_chunk.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,16 @@ def to_h
3232

3333
def decoded
3434
case encoding
35-
when 'utf8' then data
36-
when 'base64' then Base64.decode64(data)
35+
when 'utf8' then data
36+
when 'base64'
37+
# Mirror the strict encoder (Base64.strict_encode64): reject
38+
# malformed/whitespace-injected input instead of silently
39+
# truncating it into corrupt bytes.
40+
begin
41+
Base64.strict_decode64(data)
42+
rescue ArgumentError => e
43+
raise Arcp::Errors::InvalidRequest, "malformed base64 result_chunk: #{e.message}"
44+
end
3745
end
3846
end
3947
end

spec/unit/audit_findings_2026_06_11_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,25 @@ def enqueue(item) = @items << item
9292
end
9393
end
9494

95+
describe 'ResultChunk#decoded uses strict base64 (#77)' do
96+
def chunk(data)
97+
Arcp::Job::EventBody::ResultChunk.new(
98+
result_id: 'res_1', chunk_seq: 0, data: data, encoding: 'base64', more: false
99+
)
100+
end
101+
102+
it 'round-trips binary data byte-for-byte' do
103+
binary = (0..255).to_a.pack('C*')
104+
encoded = Base64.strict_encode64(binary)
105+
expect(chunk(encoded).decoded).to eq(binary)
106+
end
107+
108+
it 'raises InvalidRequest on malformed (line-wrapped/whitespace) base64' do
109+
wrapped = "#{Base64.strict_encode64('hello world payload')}\n"
110+
expect { chunk(wrapped).decoded }.to raise_error(Arcp::Errors::InvalidRequest)
111+
end
112+
end
113+
95114
describe 'EventLog#replay_job boundary helper (#75)' do
96115
it 'excludes the event equal to the strict from_event_seq cursor' do
97116
clock = Arcp::FakeClock.new

0 commit comments

Comments
 (0)