thrift 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +107 -4
- data/ext/binary_protocol_accelerated.c +52 -17
- data/ext/compact_protocol.c +135 -70
- data/ext/constants.h +3 -0
- data/ext/extconf.rb +4 -4
- data/ext/macros.h +11 -0
- data/ext/memory_buffer.c +35 -17
- data/ext/struct.c +185 -64
- data/ext/thrift_native.c +6 -0
- data/lib/thrift/bytes.rb +2 -2
- data/lib/thrift/client.rb +31 -22
- data/lib/thrift/exceptions.rb +10 -8
- data/lib/thrift/multiplexed_processor.rb +5 -6
- data/lib/thrift/processor.rb +24 -3
- data/lib/thrift/protocol/base_protocol.rb +53 -27
- data/lib/thrift/protocol/binary_protocol.rb +54 -40
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -2
- data/lib/thrift/protocol/compact_protocol.rb +193 -88
- data/lib/thrift/protocol/header_protocol.rb +14 -3
- data/lib/thrift/protocol/json_protocol.rb +146 -104
- data/lib/thrift/protocol/multiplexed_protocol.rb +2 -3
- data/lib/thrift/protocol/protocol_decorator.rb +5 -2
- data/lib/thrift/serializer/serializer.rb +6 -0
- data/lib/thrift/server/base_server.rb +10 -2
- data/lib/thrift/server/nonblocking_server.rb +49 -26
- data/lib/thrift/server/rack_application.rb +69 -0
- data/lib/thrift/server/simple_server.rb +27 -23
- data/lib/thrift/server/thin_http_server.rb +20 -44
- data/lib/thrift/server/thread_pool_server.rb +20 -17
- data/lib/thrift/server/threaded_server.rb +22 -26
- data/lib/thrift/struct.rb +33 -18
- data/lib/thrift/struct_union.rb +36 -30
- data/lib/thrift/transport/base_transport.rb +23 -5
- data/lib/thrift/transport/buffered_transport.rb +4 -4
- data/lib/thrift/transport/framed_transport.rb +32 -7
- data/lib/thrift/transport/header_transport.rb +130 -50
- data/lib/thrift/transport/http_client_transport.rb +27 -14
- data/lib/thrift/transport/io_stream_transport.rb +2 -1
- data/lib/thrift/transport/memory_buffer_transport.rb +8 -10
- data/lib/thrift/transport/server_socket.rb +4 -5
- data/lib/thrift/transport/socket.rb +20 -22
- data/lib/thrift/transport/ssl_server_socket.rb +64 -4
- data/lib/thrift/transport/ssl_socket.rb +32 -5
- data/lib/thrift/transport/unix_server_socket.rb +1 -1
- data/lib/thrift/transport/unix_socket.rb +4 -6
- data/lib/thrift/types.rb +22 -22
- data/lib/thrift/union.rb +20 -11
- data/lib/thrift/uuid.rb +8 -8
- data/lib/thrift.rb +39 -39
- metadata +5 -230
- data/benchmark/Benchmark.thrift +0 -24
- data/benchmark/benchmark.rb +0 -286
- data/benchmark/client.rb +0 -118
- data/benchmark/server.rb +0 -121
- data/benchmark/thin_server.rb +0 -46
- data/lib/thrift/server/mongrel_http_server.rb +0 -61
- data/spec/BaseService.thrift +0 -27
- data/spec/ExtendedService.thrift +0 -25
- data/spec/Referenced.thrift +0 -44
- data/spec/ThriftNamespacedSpec.thrift +0 -53
- data/spec/ThriftSpec.thrift +0 -203
- data/spec/base_protocol_spec.rb +0 -244
- data/spec/base_transport_spec.rb +0 -428
- data/spec/binary_protocol_accelerated_spec.rb +0 -47
- data/spec/binary_protocol_spec.rb +0 -73
- data/spec/binary_protocol_spec_shared.rb +0 -509
- data/spec/bytes_spec.rb +0 -117
- data/spec/client_spec.rb +0 -167
- data/spec/compact_protocol_spec.rb +0 -295
- data/spec/constants_demo_spec.rb +0 -102
- data/spec/exception_spec.rb +0 -141
- data/spec/flat_spec.rb +0 -63
- data/spec/header_protocol_spec.rb +0 -476
- data/spec/header_transport_spec.rb +0 -431
- data/spec/http_client_spec.rb +0 -160
- data/spec/json_protocol_spec.rb +0 -574
- data/spec/multiplexed_processor_spec.rb +0 -75
- data/spec/namespaced_spec.rb +0 -67
- data/spec/nonblocking_server_spec.rb +0 -429
- data/spec/processor_spec.rb +0 -80
- data/spec/recursion_depth_spec.rb +0 -223
- data/spec/serializer_spec.rb +0 -67
- data/spec/server_socket_spec.rb +0 -121
- data/spec/server_spec.rb +0 -238
- data/spec/socket_spec.rb +0 -174
- data/spec/socket_spec_shared.rb +0 -168
- data/spec/spec_helper.rb +0 -70
- data/spec/ssl_server_socket_spec.rb +0 -85
- data/spec/ssl_socket_spec.rb +0 -248
- data/spec/struct_nested_containers_spec.rb +0 -191
- data/spec/struct_spec.rb +0 -398
- data/spec/support/header_protocol_helper.rb +0 -55
- data/spec/thin_http_server_spec.rb +0 -127
- data/spec/types_spec.rb +0 -118
- data/spec/union_spec.rb +0 -273
- data/spec/unix_socket_spec.rb +0 -131
- data/spec/uuid_validation_spec.rb +0 -239
- data/test/fuzz/Makefile +0 -779
- data/test/fuzz/Makefile.am +0 -173
- data/test/fuzz/Makefile.in +0 -775
- data/test/fuzz/README.md +0 -149
- data/test/fuzz/fuzz_common.rb +0 -96
- data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_parse_json_protocol.rb +0 -23
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -23
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -23
- data/test/fuzz/fuzz_tracer.rb +0 -29
|
@@ -20,15 +20,24 @@
|
|
|
20
20
|
|
|
21
21
|
module Thrift
|
|
22
22
|
class CompactProtocol < BaseProtocol
|
|
23
|
-
|
|
24
|
-
PROTOCOL_ID = [0x82].pack('c').unpack('c').first
|
|
23
|
+
PROTOCOL_ID = [0x82].pack("c").unpack1("c")
|
|
25
24
|
VERSION = 1
|
|
26
25
|
VERSION_MASK = 0x1f
|
|
27
26
|
TYPE_MASK = 0xE0
|
|
28
27
|
TYPE_BITS = 0x07
|
|
29
28
|
TYPE_SHIFT_AMOUNT = 5
|
|
30
29
|
MAX_VARINT32_BYTES = 5 # ceil(32/7); matches protobuf wire format
|
|
30
|
+
VARINT32_PREFIX_BYTES = MAX_VARINT32_BYTES - 1
|
|
31
|
+
MAX_VARINT32_LAST_BYTE = 0x0f
|
|
31
32
|
MAX_VARINT_BYTES = 10 # ceil(64/7); matches protobuf wire format
|
|
33
|
+
BYTE_MIN = -(2**7)
|
|
34
|
+
BYTE_MAX = (2**7) - 1
|
|
35
|
+
I16_MIN = -(2**15)
|
|
36
|
+
I16_MAX = (2**15) - 1
|
|
37
|
+
I32_MIN = -(2**31)
|
|
38
|
+
I32_MAX = (2**31) - 1
|
|
39
|
+
I64_MIN = -(2**63)
|
|
40
|
+
I64_MAX = (2**63) - 1
|
|
32
41
|
|
|
33
42
|
TSTOP = [nil, Types::STOP, 0]
|
|
34
43
|
|
|
@@ -68,40 +77,53 @@ module Thrift
|
|
|
68
77
|
SET => Types::SET,
|
|
69
78
|
MAP => Types::MAP,
|
|
70
79
|
STRUCT => Types::STRUCT,
|
|
71
|
-
UUID => Types::UUID
|
|
80
|
+
UUID => Types::UUID,
|
|
72
81
|
}
|
|
73
82
|
|
|
74
83
|
TTYPE_TO_COMPACT = {
|
|
75
|
-
Types::STOP
|
|
76
|
-
Types::BOOL
|
|
77
|
-
Types::BYTE
|
|
78
|
-
Types::I16
|
|
79
|
-
Types::I32
|
|
80
|
-
Types::I64
|
|
81
|
-
Types::DOUBLE
|
|
82
|
-
Types::STRING
|
|
83
|
-
Types::LIST
|
|
84
|
-
Types::SET
|
|
85
|
-
Types::MAP
|
|
86
|
-
Types::STRUCT
|
|
87
|
-
Types::UUID
|
|
84
|
+
Types::STOP => Types::STOP,
|
|
85
|
+
Types::BOOL => BOOLEAN_TRUE,
|
|
86
|
+
Types::BYTE => BYTE,
|
|
87
|
+
Types::I16 => I16,
|
|
88
|
+
Types::I32 => I32,
|
|
89
|
+
Types::I64 => I64,
|
|
90
|
+
Types::DOUBLE => DOUBLE,
|
|
91
|
+
Types::STRING => BINARY,
|
|
92
|
+
Types::LIST => LIST,
|
|
93
|
+
Types::SET => SET,
|
|
94
|
+
Types::MAP => MAP,
|
|
95
|
+
Types::STRUCT => STRUCT,
|
|
96
|
+
Types::UUID => UUID,
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
def self.get_ttype(compact_type)
|
|
91
100
|
val = COMPACT_TO_TTYPE[compact_type & 0x0f]
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
return val if val
|
|
102
|
+
|
|
103
|
+
raise ProtocolException.new(
|
|
104
|
+
ProtocolException::INVALID_DATA,
|
|
105
|
+
"Unknown compact type: #{compact_type & 0x0f}",
|
|
106
|
+
)
|
|
94
107
|
end
|
|
95
108
|
|
|
96
109
|
def self.get_compact_type(ttype)
|
|
97
110
|
val = TTYPE_TO_COMPACT[ttype]
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
return val if val
|
|
112
|
+
|
|
113
|
+
raise ProtocolException.new(
|
|
114
|
+
ProtocolException::INVALID_DATA,
|
|
115
|
+
"Unknown compact type: #{ttype}",
|
|
116
|
+
)
|
|
100
117
|
end
|
|
101
118
|
end
|
|
102
119
|
|
|
103
|
-
|
|
120
|
+
attr_reader :max_string_size
|
|
121
|
+
|
|
122
|
+
def initialize(transport, max_string_size: DEFAULT_MAX_STRING_SIZE)
|
|
123
|
+
BaseProtocol.validate_max_string_size(max_string_size)
|
|
104
124
|
super(transport)
|
|
125
|
+
@max_string_size = max_string_size
|
|
126
|
+
@reset_message_size = transport.message_boundaries?
|
|
105
127
|
|
|
106
128
|
@last_field = [0]
|
|
107
129
|
@boolean_value = nil
|
|
@@ -111,8 +133,14 @@ module Thrift
|
|
|
111
133
|
end
|
|
112
134
|
|
|
113
135
|
def write_message_begin(name, type, seqid)
|
|
114
|
-
|
|
115
|
-
|
|
136
|
+
unless seqid.is_a?(Integer)
|
|
137
|
+
raise "nil argument not allowed!" if seqid.nil?
|
|
138
|
+
raise ::TypeError, "integer argument expected"
|
|
139
|
+
end
|
|
140
|
+
raise RangeError if seqid < I32_MIN || seqid > I32_MAX
|
|
141
|
+
|
|
142
|
+
write_byte_direct(PROTOCOL_ID)
|
|
143
|
+
write_byte_direct((VERSION & VERSION_MASK) | ((type << TYPE_SHIFT_AMOUNT) & TYPE_MASK))
|
|
116
144
|
write_varint32(message_seqid_to_varint32(seqid))
|
|
117
145
|
write_string(name)
|
|
118
146
|
nil
|
|
@@ -129,6 +157,12 @@ module Thrift
|
|
|
129
157
|
end
|
|
130
158
|
|
|
131
159
|
def write_field_begin(name, type, id)
|
|
160
|
+
unless id.is_a?(Integer)
|
|
161
|
+
raise "nil argument not allowed!" if id.nil?
|
|
162
|
+
raise ::TypeError, "integer argument expected"
|
|
163
|
+
end
|
|
164
|
+
raise RangeError if id < I16_MIN || id > I16_MAX
|
|
165
|
+
|
|
132
166
|
if type == Types::BOOL
|
|
133
167
|
# we want to possibly include the value, so we'll wait.
|
|
134
168
|
@boolean_field = [type, id]
|
|
@@ -147,16 +181,16 @@ module Thrift
|
|
|
147
181
|
last_id = @last_field.pop
|
|
148
182
|
|
|
149
183
|
# if there's a type override, use that.
|
|
150
|
-
|
|
184
|
+
type_to_write = type_override || CompactTypes.get_compact_type(type)
|
|
151
185
|
|
|
152
186
|
# check if we can use delta encoding for the field id
|
|
153
187
|
if id > last_id && id - last_id <= 15
|
|
154
188
|
# write them together
|
|
155
|
-
|
|
189
|
+
write_byte_direct(((id - last_id) << 4) | type_to_write)
|
|
156
190
|
else
|
|
157
191
|
# write them separate
|
|
158
|
-
|
|
159
|
-
|
|
192
|
+
write_byte_direct(type_to_write)
|
|
193
|
+
write_varint32(int_to_zig_zag(id))
|
|
160
194
|
end
|
|
161
195
|
|
|
162
196
|
@last_field.push(id)
|
|
@@ -164,15 +198,16 @@ module Thrift
|
|
|
164
198
|
end
|
|
165
199
|
|
|
166
200
|
def write_field_stop
|
|
167
|
-
|
|
201
|
+
write_byte_direct(Types::STOP)
|
|
168
202
|
end
|
|
169
203
|
|
|
170
204
|
def write_map_begin(ktype, vtype, size)
|
|
205
|
+
size = validate_size(size)
|
|
171
206
|
if (size == 0)
|
|
172
|
-
|
|
207
|
+
write_byte_direct(0)
|
|
173
208
|
else
|
|
174
209
|
write_varint32(size)
|
|
175
|
-
|
|
210
|
+
write_byte_direct((CompactTypes.get_compact_type(ktype) << 4) | CompactTypes.get_compact_type(vtype))
|
|
176
211
|
end
|
|
177
212
|
end
|
|
178
213
|
|
|
@@ -185,6 +220,7 @@ module Thrift
|
|
|
185
220
|
end
|
|
186
221
|
|
|
187
222
|
def write_bool(bool)
|
|
223
|
+
# Preserve Ruby truthiness: only false and nil encode as false.
|
|
188
224
|
type = bool ? CompactTypes::BOOLEAN_TRUE : CompactTypes::BOOLEAN_FALSE
|
|
189
225
|
unless @boolean_field.nil?
|
|
190
226
|
# we haven't written the field header yet
|
|
@@ -192,23 +228,47 @@ module Thrift
|
|
|
192
228
|
@boolean_field = nil
|
|
193
229
|
else
|
|
194
230
|
# we're not part of a field, so just write the value.
|
|
195
|
-
|
|
231
|
+
write_byte_direct(type)
|
|
196
232
|
end
|
|
197
233
|
end
|
|
198
234
|
|
|
199
235
|
def write_byte(byte)
|
|
200
|
-
|
|
236
|
+
unless byte.is_a?(Integer)
|
|
237
|
+
raise "nil argument not allowed!" if byte.nil?
|
|
238
|
+
raise ::TypeError, "integer argument expected"
|
|
239
|
+
end
|
|
240
|
+
raise RangeError if byte < BYTE_MIN || byte > BYTE_MAX
|
|
241
|
+
|
|
242
|
+
write_byte_direct(byte)
|
|
201
243
|
end
|
|
202
244
|
|
|
203
245
|
def write_i16(i16)
|
|
246
|
+
unless i16.is_a?(Integer)
|
|
247
|
+
raise "nil argument not allowed!" if i16.nil?
|
|
248
|
+
raise ::TypeError, "integer argument expected"
|
|
249
|
+
end
|
|
250
|
+
raise RangeError if i16 < I16_MIN || i16 > I16_MAX
|
|
251
|
+
|
|
204
252
|
write_varint32(int_to_zig_zag(i16))
|
|
205
253
|
end
|
|
206
254
|
|
|
207
255
|
def write_i32(i32)
|
|
256
|
+
unless i32.is_a?(Integer)
|
|
257
|
+
raise "nil argument not allowed!" if i32.nil?
|
|
258
|
+
raise ::TypeError, "integer argument expected"
|
|
259
|
+
end
|
|
260
|
+
raise RangeError if i32 < I32_MIN || i32 > I32_MAX
|
|
261
|
+
|
|
208
262
|
write_varint32(int_to_zig_zag(i32))
|
|
209
263
|
end
|
|
210
264
|
|
|
211
265
|
def write_i64(i64)
|
|
266
|
+
unless i64.is_a?(Integer)
|
|
267
|
+
raise "nil argument not allowed!" if i64.nil?
|
|
268
|
+
raise ::TypeError, "integer argument expected"
|
|
269
|
+
end
|
|
270
|
+
raise RangeError if i64 < I64_MIN || i64 > I64_MAX
|
|
271
|
+
|
|
212
272
|
write_varint64(long_to_zig_zag(i64))
|
|
213
273
|
end
|
|
214
274
|
|
|
@@ -222,7 +282,8 @@ module Thrift
|
|
|
222
282
|
end
|
|
223
283
|
|
|
224
284
|
def write_binary(buf)
|
|
225
|
-
|
|
285
|
+
size = validate_size(buf.bytesize)
|
|
286
|
+
write_varint32(size)
|
|
226
287
|
@trans.write(buf)
|
|
227
288
|
end
|
|
228
289
|
|
|
@@ -232,20 +293,28 @@ module Thrift
|
|
|
232
293
|
end
|
|
233
294
|
|
|
234
295
|
def read_message_begin
|
|
235
|
-
|
|
296
|
+
trans.reset_message_size if @reset_message_size
|
|
297
|
+
|
|
298
|
+
protocol_id = read_byte
|
|
236
299
|
if protocol_id != PROTOCOL_ID
|
|
237
|
-
raise ProtocolException.new(
|
|
300
|
+
raise ProtocolException.new(
|
|
301
|
+
ProtocolException::BAD_VERSION,
|
|
302
|
+
"Expected protocol id #{PROTOCOL_ID} but got #{protocol_id}",
|
|
303
|
+
)
|
|
238
304
|
end
|
|
239
305
|
|
|
240
|
-
version_and_type = read_byte
|
|
306
|
+
version_and_type = read_byte
|
|
241
307
|
version = version_and_type & VERSION_MASK
|
|
242
308
|
if (version != VERSION)
|
|
243
|
-
raise ProtocolException.new(
|
|
309
|
+
raise ProtocolException.new(
|
|
310
|
+
ProtocolException::BAD_VERSION,
|
|
311
|
+
"Expected version #{VERSION} but got #{version}",
|
|
312
|
+
)
|
|
244
313
|
end
|
|
245
314
|
|
|
246
315
|
type = (version_and_type >> TYPE_SHIFT_AMOUNT) & TYPE_BITS
|
|
247
|
-
seqid = message_seqid_from_varint32(read_varint32
|
|
248
|
-
messageName = read_string
|
|
316
|
+
seqid = message_seqid_from_varint32(read_varint32)
|
|
317
|
+
messageName = read_string
|
|
249
318
|
[messageName, type, seqid]
|
|
250
319
|
end
|
|
251
320
|
|
|
@@ -255,12 +324,12 @@ module Thrift
|
|
|
255
324
|
end
|
|
256
325
|
|
|
257
326
|
def read_struct_end
|
|
258
|
-
@last_field.pop
|
|
327
|
+
@last_field.pop
|
|
259
328
|
nil
|
|
260
329
|
end
|
|
261
330
|
|
|
262
331
|
def read_field_begin
|
|
263
|
-
type = read_byte
|
|
332
|
+
type = read_byte
|
|
264
333
|
|
|
265
334
|
# if it's a stop, then we can return immediately, as the struct is over.
|
|
266
335
|
if (type & 0x0f) == Types::STOP
|
|
@@ -273,7 +342,7 @@ module Thrift
|
|
|
273
342
|
if modifier == 0
|
|
274
343
|
# not a delta. look ahead for the zigzag varint field id.
|
|
275
344
|
@last_field.pop
|
|
276
|
-
field_id = read_i16
|
|
345
|
+
field_id = read_i16
|
|
277
346
|
else
|
|
278
347
|
# has a delta. add the delta to the last read field id.
|
|
279
348
|
field_id = @last_field.pop + modifier
|
|
@@ -292,17 +361,19 @@ module Thrift
|
|
|
292
361
|
end
|
|
293
362
|
|
|
294
363
|
def read_map_begin
|
|
295
|
-
size = read_varint32
|
|
296
|
-
|
|
364
|
+
size = read_varint32
|
|
365
|
+
validate_container_size(size)
|
|
366
|
+
key_and_value_type = size == 0 ? 0 : read_byte
|
|
297
367
|
[CompactTypes.get_ttype(key_and_value_type >> 4), CompactTypes.get_ttype(key_and_value_type & 0xf), size]
|
|
298
368
|
end
|
|
299
369
|
|
|
300
370
|
def read_list_begin
|
|
301
|
-
size_and_type = read_byte
|
|
371
|
+
size_and_type = read_byte
|
|
302
372
|
size = (size_and_type >> 4) & 0x0f
|
|
303
373
|
if size == 15
|
|
304
|
-
size = read_varint32
|
|
374
|
+
size = read_varint32
|
|
305
375
|
end
|
|
376
|
+
validate_container_size(size)
|
|
306
377
|
type = CompactTypes.get_ttype(size_and_type)
|
|
307
378
|
[type, size]
|
|
308
379
|
end
|
|
@@ -317,7 +388,7 @@ module Thrift
|
|
|
317
388
|
@bool_value = nil
|
|
318
389
|
bv
|
|
319
390
|
else
|
|
320
|
-
read_byte
|
|
391
|
+
read_byte == CompactTypes::BOOLEAN_TRUE
|
|
321
392
|
end
|
|
322
393
|
end
|
|
323
394
|
|
|
@@ -330,21 +401,21 @@ module Thrift
|
|
|
330
401
|
end
|
|
331
402
|
|
|
332
403
|
def read_i16
|
|
333
|
-
zig_zag_to_int(read_varint32
|
|
404
|
+
value = zig_zag_to_int(read_varint32) & 0xffff
|
|
405
|
+
value > I16_MAX ? value - 0x10000 : value
|
|
334
406
|
end
|
|
335
407
|
|
|
336
408
|
def read_i32
|
|
337
|
-
zig_zag_to_int(read_varint32
|
|
409
|
+
zig_zag_to_int(read_varint32)
|
|
338
410
|
end
|
|
339
411
|
|
|
340
412
|
def read_i64
|
|
341
|
-
zig_zag_to_long(read_varint64
|
|
413
|
+
zig_zag_to_long(read_varint64 & 0xffffffffffffffff)
|
|
342
414
|
end
|
|
343
415
|
|
|
344
416
|
def read_double
|
|
345
417
|
trans.read_into_buffer(@rbuf, 8)
|
|
346
|
-
|
|
347
|
-
val
|
|
418
|
+
@rbuf.reverse.unpack1("G")
|
|
348
419
|
end
|
|
349
420
|
|
|
350
421
|
def read_string
|
|
@@ -353,16 +424,24 @@ module Thrift
|
|
|
353
424
|
end
|
|
354
425
|
|
|
355
426
|
def read_binary
|
|
356
|
-
size = read_varint32
|
|
427
|
+
size = read_varint32
|
|
428
|
+
if size > I32_MAX
|
|
429
|
+
raise ProtocolException.new(ProtocolException::SIZE_LIMIT, "Binary size limit exceeded")
|
|
430
|
+
end
|
|
431
|
+
check_string_size(size)
|
|
357
432
|
trans.read_all(size)
|
|
358
433
|
end
|
|
359
434
|
|
|
435
|
+
def skip_string
|
|
436
|
+
read_binary
|
|
437
|
+
end
|
|
438
|
+
|
|
360
439
|
def read_uuid
|
|
361
440
|
UUID.uuid_from_bytes(trans.read_all(16))
|
|
362
441
|
end
|
|
363
442
|
|
|
364
443
|
def to_s
|
|
365
|
-
"compact(#{super
|
|
444
|
+
"compact(#{super})"
|
|
366
445
|
end
|
|
367
446
|
|
|
368
447
|
private
|
|
@@ -372,68 +451,84 @@ module Thrift
|
|
|
372
451
|
# the wire differ only by the type indicator.
|
|
373
452
|
#
|
|
374
453
|
def write_collection_begin(elem_type, size)
|
|
454
|
+
size = validate_size(size)
|
|
455
|
+
compact_type = CompactTypes.get_compact_type(elem_type)
|
|
375
456
|
if size <= 14
|
|
376
|
-
|
|
457
|
+
write_byte_direct((size << 4) | compact_type)
|
|
377
458
|
else
|
|
378
|
-
|
|
459
|
+
write_byte_direct(0xf0 | compact_type)
|
|
379
460
|
write_varint32(size)
|
|
380
461
|
end
|
|
381
462
|
end
|
|
382
463
|
|
|
464
|
+
def write_byte_direct(byte)
|
|
465
|
+
@trans.write([byte].pack("C"))
|
|
466
|
+
end
|
|
467
|
+
|
|
383
468
|
def write_varint32(n)
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
# i32buf[idx++] = (byte)n;
|
|
388
|
-
write_byte(n)
|
|
389
|
-
break
|
|
390
|
-
# return;
|
|
391
|
-
else
|
|
392
|
-
# i32buf[idx++] = (byte)((n & 0x7F) | 0x80);
|
|
393
|
-
write_byte((n & 0x7F) | 0x80)
|
|
394
|
-
n = n >> 7
|
|
395
|
-
end
|
|
469
|
+
if (n & ~0x7F) == 0
|
|
470
|
+
write_byte_direct(n)
|
|
471
|
+
return
|
|
396
472
|
end
|
|
397
|
-
|
|
473
|
+
|
|
474
|
+
buffer = String.new(capacity: MAX_VARINT32_BYTES, encoding: Encoding::BINARY)
|
|
475
|
+
while (n & ~0x7F) != 0
|
|
476
|
+
buffer << ((n & 0x7F) | 0x80)
|
|
477
|
+
n >>= 7
|
|
478
|
+
end
|
|
479
|
+
buffer << n
|
|
480
|
+
@trans.write(buffer)
|
|
398
481
|
end
|
|
399
482
|
|
|
400
483
|
SEVEN_BIT_MASK = 0x7F
|
|
401
484
|
EVERYTHING_ELSE_MASK = ~SEVEN_BIT_MASK
|
|
402
485
|
|
|
403
486
|
def write_varint64(n)
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
487
|
+
if (n & EVERYTHING_ELSE_MASK) == 0
|
|
488
|
+
write_byte_direct(n)
|
|
489
|
+
return
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
buffer = String.new(capacity: MAX_VARINT_BYTES, encoding: Encoding::BINARY)
|
|
493
|
+
while (n & EVERYTHING_ELSE_MASK) != 0
|
|
494
|
+
buffer << ((n & SEVEN_BIT_MASK) | 0x80)
|
|
495
|
+
n >>= 7
|
|
412
496
|
end
|
|
497
|
+
buffer << n
|
|
498
|
+
@trans.write(buffer)
|
|
413
499
|
end
|
|
414
500
|
|
|
415
|
-
def read_varint32
|
|
501
|
+
def read_varint32
|
|
416
502
|
shift = 0
|
|
417
503
|
result = 0
|
|
418
|
-
|
|
419
|
-
b = read_byte
|
|
504
|
+
VARINT32_PREFIX_BYTES.times do
|
|
505
|
+
b = read_byte
|
|
420
506
|
result |= (b & 0x7f) << shift
|
|
421
507
|
return result if (b & 0x80) != 0x80
|
|
422
508
|
shift += 7
|
|
423
509
|
end
|
|
424
|
-
|
|
510
|
+
|
|
511
|
+
b = read_byte
|
|
512
|
+
if (b & 0x80) != 0
|
|
513
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Variable-length int over 5 bytes.")
|
|
514
|
+
end
|
|
515
|
+
if (b & ~MAX_VARINT32_LAST_BYTE) != 0
|
|
516
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Variable-length int overflows uint32.")
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
result | (b << shift)
|
|
425
520
|
end
|
|
426
521
|
|
|
427
|
-
def read_varint64
|
|
522
|
+
def read_varint64
|
|
428
523
|
shift = 0
|
|
429
524
|
result = 0
|
|
430
525
|
MAX_VARINT_BYTES.times do
|
|
431
|
-
b = read_byte
|
|
526
|
+
b = read_byte
|
|
432
527
|
result |= (b & 0x7f) << shift
|
|
433
528
|
return result if (b & 0x80) != 0x80
|
|
434
529
|
shift += 7
|
|
435
530
|
end
|
|
436
|
-
raise ProtocolException.new(ProtocolException::INVALID_DATA,
|
|
531
|
+
raise ProtocolException.new(ProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.")
|
|
437
532
|
end
|
|
438
533
|
|
|
439
534
|
def int_to_zig_zag(n)
|
|
@@ -454,11 +549,17 @@ module Thrift
|
|
|
454
549
|
end
|
|
455
550
|
|
|
456
551
|
def message_seqid_to_varint32(seqid)
|
|
457
|
-
|
|
458
|
-
|
|
552
|
+
seqid < 0 ? seqid + (2**32) : seqid
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def validate_size(size)
|
|
556
|
+
unless size.is_a?(Integer)
|
|
557
|
+
raise "nil argument not allowed!" if size.nil?
|
|
558
|
+
raise ::TypeError, "integer argument expected"
|
|
459
559
|
end
|
|
560
|
+
raise RangeError if size < 0 || size > I32_MAX
|
|
460
561
|
|
|
461
|
-
|
|
562
|
+
size
|
|
462
563
|
end
|
|
463
564
|
|
|
464
565
|
def message_seqid_from_varint32(seqid)
|
|
@@ -467,8 +568,12 @@ module Thrift
|
|
|
467
568
|
end
|
|
468
569
|
|
|
469
570
|
class CompactProtocolFactory < BaseProtocolFactory
|
|
571
|
+
def initialize(max_string_size: BaseProtocol::DEFAULT_MAX_STRING_SIZE)
|
|
572
|
+
@max_string_size = max_string_size
|
|
573
|
+
end
|
|
574
|
+
|
|
470
575
|
def get_protocol(trans)
|
|
471
|
-
CompactProtocol.new(trans)
|
|
576
|
+
CompactProtocol.new(trans, max_string_size: @max_string_size)
|
|
472
577
|
end
|
|
473
578
|
|
|
474
579
|
def to_s
|
|
@@ -178,8 +178,9 @@ module Thrift
|
|
|
178
178
|
@header_transport.reset_protocol
|
|
179
179
|
reset_protocol_if_needed
|
|
180
180
|
rescue ProtocolException => ex
|
|
181
|
+
use_default_protocol
|
|
181
182
|
app_ex = ApplicationException.new(ApplicationException::INVALID_PROTOCOL, ex.message)
|
|
182
|
-
write_message_begin("", MessageTypes::EXCEPTION,
|
|
183
|
+
write_message_begin("", MessageTypes::EXCEPTION, @header_transport.sequence_id)
|
|
183
184
|
app_ex.write(self)
|
|
184
185
|
write_message_end
|
|
185
186
|
@header_transport.flush
|
|
@@ -264,12 +265,16 @@ module Thrift
|
|
|
264
265
|
@protocol.read_binary
|
|
265
266
|
end
|
|
266
267
|
|
|
268
|
+
def skip_string
|
|
269
|
+
@protocol.skip_string
|
|
270
|
+
end
|
|
271
|
+
|
|
267
272
|
def read_uuid
|
|
268
273
|
@protocol.read_uuid
|
|
269
274
|
end
|
|
270
275
|
|
|
271
276
|
def to_s
|
|
272
|
-
"header(#{@protocol
|
|
277
|
+
"header(#{@protocol})"
|
|
273
278
|
end
|
|
274
279
|
|
|
275
280
|
private
|
|
@@ -283,6 +288,12 @@ module Thrift
|
|
|
283
288
|
end
|
|
284
289
|
end
|
|
285
290
|
|
|
291
|
+
def use_default_protocol
|
|
292
|
+
@protocol = create_protocol(@default_protocol)
|
|
293
|
+
@current_protocol_id = @default_protocol
|
|
294
|
+
@header_transport.protocol_id = @default_protocol
|
|
295
|
+
end
|
|
296
|
+
|
|
286
297
|
# Creates a protocol instance based on protocol ID
|
|
287
298
|
def create_protocol(protocol_id)
|
|
288
299
|
case protocol_id
|
|
@@ -293,7 +304,7 @@ module Thrift
|
|
|
293
304
|
else
|
|
294
305
|
raise ProtocolException.new(
|
|
295
306
|
ProtocolException::INVALID_DATA,
|
|
296
|
-
"Unknown protocol ID: #{protocol_id}"
|
|
307
|
+
"Unknown protocol ID: #{protocol_id}",
|
|
297
308
|
)
|
|
298
309
|
end
|
|
299
310
|
end
|