Skip to content

Commit 64601a5

Browse files
kpumukcodex
andcommitted
THRIFT-6133: Handle oversized Ruby memory-buffer reads
Client: rb Co-Authored-By: OpenAI Codex (GPT-5.6) <codex@openai.com>
1 parent 2ae9c11 commit 64601a5

2 files changed

Lines changed: 18 additions & 12 deletions

File tree

lib/rb/ext/memory_buffer.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,28 @@ VALUE rb_thrift_memory_buffer_write(VALUE self, VALUE str) {
4848
}
4949

5050
VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
51-
int length = FIX2INT(length_value);
51+
long long length = NUM2LL(length_value);
5252

5353
if (RB_UNLIKELY(length < 0)) {
5454
rb_exc_raise(rb_funcall(transport_exception_class, new_method_id, 2, transport_negative_size, rb_str_new2("Negative size")));
5555
}
5656

5757
VALUE index_value = rb_ivar_get(self, index_ivar_id);
58-
int index = FIX2INT(index_value);
58+
long index = NUM2LONG(index_value);
5959

6060
VALUE buf = GET_BUF(self);
6161
VALUE data = rb_funcall(buf, slice_method_id, 2, index_value, length_value);
6262

6363
if (length > RSTRING_LEN(buf) - index) {
64-
index = (int)RSTRING_LEN(buf);
64+
index = RSTRING_LEN(buf);
6565
} else {
66-
index += length;
66+
index += (long)length;
6767
}
6868
if (index >= GARBAGE_BUFFER_SIZE) {
69-
rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, INT2FIX(index), INT2FIX(RSTRING_LEN(buf) - 1)));
69+
rb_ivar_set(self, buf_ivar_id, rb_funcall(buf, slice_method_id, 2, LONG2NUM(index), LONG2NUM(RSTRING_LEN(buf) - 1)));
7070
index = 0;
7171
}
72-
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
72+
rb_ivar_set(self, index_ivar_id, LONG2NUM(index));
7373

7474
if (RSTRING_LEN(data) < length) {
7575
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
@@ -79,28 +79,28 @@ VALUE rb_thrift_memory_buffer_read(VALUE self, VALUE length_value) {
7979
}
8080

8181
VALUE rb_thrift_memory_buffer_read_all(VALUE self, VALUE length_value) {
82-
int length = FIX2INT(length_value);
82+
long long length = NUM2LL(length_value);
8383

8484
if (RB_UNLIKELY(length < 0)) {
8585
rb_exc_raise(rb_funcall(transport_exception_class, new_method_id, 2, transport_negative_size, rb_str_new2("Negative size")));
8686
}
8787

8888
VALUE index_value = rb_ivar_get(self, index_ivar_id);
89-
int index = FIX2INT(index_value);
89+
long index = NUM2LONG(index_value);
9090
VALUE buf = GET_BUF(self);
9191

9292
if (RB_UNLIKELY(length > RSTRING_LEN(buf) - index)) {
9393
rb_raise(rb_eEOFError, "Not enough bytes remain in memory buffer");
9494
}
9595

96-
VALUE data = rb_str_subseq(buf, index, length);
96+
VALUE data = rb_str_subseq(buf, index, (long)length);
9797

98-
index += length;
98+
index += (long)length;
9999
if (index >= GARBAGE_BUFFER_SIZE) {
100100
rb_ivar_set(self, buf_ivar_id, rb_str_subseq(buf, index, RSTRING_LEN(buf) - index));
101101
index = 0;
102102
}
103-
rb_ivar_set(self, index_ivar_id, INT2FIX(index));
103+
rb_ivar_set(self, index_ivar_id, LONG2NUM(index));
104104

105105
return data;
106106
}

lib/rb/spec/base_transport_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@
394394
@buffer.reset_buffer("abcd")
395395

396396
expect(@buffer.read(1)).to eq("a")
397-
expect { @buffer.read((2**31) - 1) }.to raise_error(EOFError)
397+
expect { @buffer.read(2**31) }.to raise_error(EOFError)
398398
expect(@buffer.available).to eq(0)
399399
end
400400

@@ -465,6 +465,12 @@
465465
expect(e.type).to eq(Thrift::TransportException::NEGATIVE_SIZE)
466466
end
467467
end
468+
469+
it "should handle oversized read_all sizes without overflowing" do
470+
@buffer.reset_buffer("x")
471+
472+
expect { @buffer.read_all(3_397_380_576) }.to raise_error(EOFError)
473+
end
468474
end
469475

470476
describe Thrift::IOStreamTransport do

0 commit comments

Comments
 (0)