thrift 0.22.0 → 0.24.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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +235 -17
  3. data/benchmark/benchmark.rb +23 -8
  4. data/benchmark/client.rb +50 -6
  5. data/benchmark/server.rb +46 -7
  6. data/benchmark/thin_server.rb +2 -0
  7. data/ext/binary_protocol_accelerated.c +154 -42
  8. data/ext/bytes.c +14 -0
  9. data/ext/compact_protocol.c +138 -45
  10. data/ext/constants.h +12 -0
  11. data/ext/extconf.rb +17 -8
  12. data/ext/memory_buffer.c +44 -7
  13. data/ext/protocol.c +29 -0
  14. data/ext/protocol.h +35 -0
  15. data/ext/struct.c +48 -17
  16. data/ext/thrift_native.c +28 -3
  17. data/lib/thrift/bytes.rb +70 -100
  18. data/lib/thrift/client.rb +54 -13
  19. data/lib/thrift/exceptions.rb +6 -5
  20. data/lib/thrift/multiplexed_processor.rb +20 -10
  21. data/lib/thrift/processor.rb +7 -6
  22. data/lib/thrift/protocol/base_protocol.rb +52 -21
  23. data/lib/thrift/protocol/binary_protocol.rb +65 -20
  24. data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -5
  25. data/lib/thrift/protocol/compact_protocol.rb +76 -41
  26. data/lib/thrift/protocol/header_protocol.rb +321 -0
  27. data/lib/thrift/protocol/json_protocol.rb +44 -27
  28. data/lib/thrift/protocol/multiplexed_protocol.rb +6 -5
  29. data/lib/thrift/protocol/protocol_decorator.rb +13 -4
  30. data/lib/thrift/serializer/deserializer.rb +6 -5
  31. data/lib/thrift/serializer/serializer.rb +5 -5
  32. data/lib/thrift/server/base_server.rb +5 -4
  33. data/lib/thrift/server/mongrel_http_server.rb +7 -6
  34. data/lib/thrift/server/nonblocking_server.rb +35 -9
  35. data/lib/thrift/server/simple_server.rb +13 -5
  36. data/lib/thrift/server/thin_http_server.rb +4 -3
  37. data/lib/thrift/server/thread_pool_server.rb +7 -6
  38. data/lib/thrift/server/threaded_server.rb +13 -5
  39. data/lib/thrift/struct.rb +12 -11
  40. data/lib/thrift/struct_union.rb +14 -9
  41. data/lib/thrift/thrift_native.rb +3 -2
  42. data/lib/thrift/transport/base_server_transport.rb +8 -5
  43. data/lib/thrift/transport/base_transport.rb +18 -14
  44. data/lib/thrift/transport/buffered_transport.rb +7 -6
  45. data/lib/thrift/transport/framed_transport.rb +8 -7
  46. data/lib/thrift/transport/header_transport.rb +562 -0
  47. data/lib/thrift/transport/http_client_transport.rb +2 -1
  48. data/lib/thrift/transport/io_stream_transport.rb +4 -3
  49. data/lib/thrift/transport/memory_buffer_transport.rb +13 -6
  50. data/lib/thrift/transport/server_socket.rb +14 -8
  51. data/lib/thrift/transport/socket.rb +126 -60
  52. data/lib/thrift/transport/ssl_server_socket.rb +4 -3
  53. data/lib/thrift/transport/ssl_socket.rb +45 -13
  54. data/lib/thrift/transport/unix_server_socket.rb +9 -5
  55. data/lib/thrift/transport/unix_socket.rb +7 -6
  56. data/lib/thrift/types.rb +10 -6
  57. data/lib/thrift/union.rb +15 -8
  58. data/lib/thrift/uuid.rb +50 -0
  59. data/lib/thrift.rb +4 -1
  60. data/spec/ThriftSpec.thrift +21 -1
  61. data/spec/base_protocol_spec.rb +21 -2
  62. data/spec/base_transport_spec.rb +48 -8
  63. data/spec/binary_protocol_accelerated_spec.rb +1 -0
  64. data/spec/binary_protocol_spec.rb +1 -2
  65. data/spec/binary_protocol_spec_shared.rb +206 -155
  66. data/spec/bytes_spec.rb +71 -114
  67. data/spec/client_spec.rb +86 -19
  68. data/spec/compact_protocol_spec.rb +153 -16
  69. data/spec/constants_demo_spec.rb +102 -0
  70. data/spec/exception_spec.rb +1 -1
  71. data/spec/flat_spec.rb +1 -0
  72. data/spec/header_protocol_spec.rb +476 -0
  73. data/spec/header_transport_spec.rb +431 -0
  74. data/spec/http_client_spec.rb +5 -6
  75. data/spec/json_protocol_spec.rb +69 -47
  76. data/spec/multiplexed_processor_spec.rb +75 -0
  77. data/spec/namespaced_spec.rb +1 -1
  78. data/spec/nonblocking_server_spec.rb +174 -8
  79. data/spec/processor_spec.rb +1 -1
  80. data/spec/recursion_depth_spec.rb +223 -0
  81. data/spec/serializer_spec.rb +1 -1
  82. data/spec/server_socket_spec.rb +38 -1
  83. data/spec/server_spec.rb +60 -9
  84. data/spec/socket_spec.rb +119 -13
  85. data/spec/socket_spec_shared.rb +73 -9
  86. data/spec/spec_helper.rb +2 -1
  87. data/spec/ssl_server_socket_spec.rb +52 -1
  88. data/spec/ssl_socket_spec.rb +181 -11
  89. data/spec/struct_nested_containers_spec.rb +2 -2
  90. data/spec/struct_spec.rb +114 -9
  91. data/spec/support/header_protocol_helper.rb +55 -0
  92. data/spec/thin_http_server_spec.rb +4 -18
  93. data/spec/types_spec.rb +26 -26
  94. data/spec/union_spec.rb +70 -11
  95. data/spec/unix_socket_spec.rb +17 -2
  96. data/spec/uuid_validation_spec.rb +239 -0
  97. data/test/fuzz/Makefile +779 -0
  98. data/test/fuzz/Makefile.am +173 -0
  99. data/test/fuzz/Makefile.in +775 -0
  100. data/test/fuzz/README.md +149 -0
  101. data/test/fuzz/fuzz_common.rb +96 -0
  102. data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +4 -4
  103. data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +7 -13
  104. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +23 -0
  105. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +23 -0
  106. data/test/fuzz/fuzz_parse_compact_protocol.rb +23 -0
  107. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +23 -0
  108. data/test/fuzz/fuzz_parse_json_protocol.rb +23 -0
  109. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +23 -0
  110. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +23 -0
  111. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +23 -0
  112. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +23 -0
  113. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +23 -0
  114. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +23 -0
  115. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +23 -0
  116. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +23 -0
  117. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +23 -0
  118. data/test/fuzz/fuzz_tracer.rb +29 -0
  119. metadata +105 -70
@@ -1,4 +1,5 @@
1
- #
1
+ # frozen_string_literal: true
2
+ #
2
3
  # Licensed to the Apache Software Foundation (ASF) under one
3
4
  # or more contributor license agreements. See the NOTICE file
4
5
  # distributed with this work for additional information
@@ -6,9 +7,9 @@
6
7
  # to you under the Apache License, Version 2.0 (the
7
8
  # "License"); you may not use this file except in compliance
8
9
  # with the License. You may obtain a copy of the License at
9
- #
10
+ #
10
11
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
+ #
12
13
  # Unless required by applicable law or agreed to in writing,
13
14
  # software distributed under the License is distributed on an
14
15
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -23,17 +24,26 @@ module Thrift
23
24
  class MultiplexedProcessor
24
25
  def initialize
25
26
  @actual_processors = {}
27
+ @default_processor = nil
26
28
  end
27
-
29
+
28
30
  def register_processor(service_name, processor)
29
31
  @actual_processors[service_name] = processor
30
32
  end
31
-
33
+
34
+ def register_default(processor)
35
+ @default_processor = processor
36
+ end
37
+
32
38
  def process(iprot, oprot)
33
39
  name, type, seqid = iprot.read_message_begin
34
40
  check_type(type)
35
- check_separator(name)
36
- service_name, method = name.split(':')
41
+ if name.count(':') < 1
42
+ check_default_processor(name)
43
+ return @default_processor.process(StoredMessageProtocol.new(iprot, [name, type, seqid]), oprot)
44
+ end
45
+
46
+ service_name, method = name.split(':', 2)
37
47
  processor(service_name).process(StoredMessageProtocol.new(iprot, [method, type, seqid]), oprot)
38
48
  end
39
49
 
@@ -53,8 +63,8 @@ module Thrift
53
63
  end
54
64
  end
55
65
 
56
- def check_separator(name)
57
- if name.count(':') < 1
66
+ def check_default_processor(name)
67
+ unless @default_processor
58
68
  raise Thrift::Exception.new("Service name not found in message name: #{name}. Did you forget to use a Thrift::Protocol::MultiplexedProtocol in your client?")
59
69
  end
60
70
  end
@@ -63,7 +73,7 @@ module Thrift
63
73
  class StoredMessageProtocol < BaseProtocol
64
74
 
65
75
  include ProtocolDecorator
66
-
76
+
67
77
  def initialize(protocol, message_begin)
68
78
  super(protocol)
69
79
  @message_begin = message_begin
@@ -1,4 +1,5 @@
1
- #
1
+ # frozen_string_literal: true
2
+ #
2
3
  # Licensed to the Apache Software Foundation (ASF) under one
3
4
  # or more contributor license agreements. See the NOTICE file
4
5
  # distributed with this work for additional information
@@ -6,22 +7,22 @@
6
7
  # to you under the Apache License, Version 2.0 (the
7
8
  # "License"); you may not use this file except in compliance
8
9
  # with the License. You may obtain a copy of the License at
9
- #
10
+ #
10
11
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
+ #
12
13
  # Unless required by applicable law or agreed to in writing,
13
14
  # software distributed under the License is distributed on an
14
15
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
16
  # KIND, either express or implied. See the License for the
16
17
  # specific language governing permissions and limitations
17
18
  # under the License.
18
- #
19
+ #
19
20
 
20
21
  require 'logger'
21
22
 
22
23
  module Thrift
23
24
  module Processor
24
- def initialize(handler, logger=nil)
25
+ def initialize(handler, logger = nil)
25
26
  @handler = handler
26
27
  if logger.nil?
27
28
  @logger = Logger.new(STDERR)
@@ -32,7 +33,7 @@ module Thrift
32
33
  end
33
34
 
34
35
  def process(iprot, oprot)
35
- name, type, seqid = iprot.read_message_begin
36
+ name, type, seqid = iprot.read_message_begin
36
37
  if respond_to?("process_#{name}")
37
38
  begin
38
39
  send("process_#{name}", seqid, iprot, oprot)
@@ -1,4 +1,5 @@
1
- #
1
+ # frozen_string_literal: true
2
+ #
2
3
  # Licensed to the Apache Software Foundation (ASF) under one
3
4
  # or more contributor license agreements. See the NOTICE file
4
5
  # distributed with this work for additional information
@@ -6,16 +7,16 @@
6
7
  # to you under the Apache License, Version 2.0 (the
7
8
  # "License"); you may not use this file except in compliance
8
9
  # with the License. You may obtain a copy of the License at
9
- #
10
+ #
10
11
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
+ #
12
13
  # Unless required by applicable law or agreed to in writing,
13
14
  # software distributed under the License is distributed on an
14
15
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
16
  # KIND, either express or implied. See the License for the
16
17
  # specific language governing permissions and limitations
17
18
  # under the License.
18
- #
19
+ #
19
20
 
20
21
  # this require is to make generated struct definitions happy
21
22
  require 'set'
@@ -33,7 +34,7 @@ module Thrift
33
34
 
34
35
  attr_reader :type
35
36
 
36
- def initialize(type=UNKNOWN, message=nil)
37
+ def initialize(type = UNKNOWN, message = nil)
37
38
  super(message)
38
39
  @type = type
39
40
  end
@@ -116,7 +117,7 @@ module Thrift
116
117
  raise NotImplementedError
117
118
  end
118
119
 
119
- # Writes a Thrift String. In Ruby 1.9+, the String passed will be transcoded to UTF-8.
120
+ # Writes a Thrift String. The String passed will be transcoded to UTF-8.
120
121
  #
121
122
  # str - The String to write.
122
123
  #
@@ -127,7 +128,7 @@ module Thrift
127
128
  raise NotImplementedError
128
129
  end
129
130
 
130
- # Writes a Thrift Binary (Thrift String with no encoding). In Ruby 1.9+, the String passed
131
+ # Writes a Thrift Binary (Thrift String with no encoding). The String passed
131
132
  # will forced into BINARY encoding.
132
133
  #
133
134
  # buf - The String to write.
@@ -137,6 +138,15 @@ module Thrift
137
138
  raise NotImplementedError
138
139
  end
139
140
 
141
+ # Writes a UUID as 16 bytes.
142
+ #
143
+ # uuid - The UUID string to write (e.g. "550e8400-e29b-41d4-a716-446655440000").
144
+ #
145
+ # Returns nothing.
146
+ def write_uuid(uuid)
147
+ raise NotImplementedError
148
+ end
149
+
140
150
  def read_message_begin
141
151
  raise NotImplementedError
142
152
  end
@@ -197,14 +207,14 @@ module Thrift
197
207
  raise NotImplementedError
198
208
  end
199
209
 
200
- # Reads a Thrift String. In Ruby 1.9+, all Strings will be returned with an Encoding of UTF-8.
210
+ # Reads a Thrift String. All Strings will be returned with an Encoding of UTF-8.
201
211
  #
202
212
  # Returns a String.
203
213
  def read_string
204
214
  raise NotImplementedError
205
215
  end
206
216
 
207
- # Reads a Thrift Binary (Thrift String without encoding). In Ruby 1.9+, all Strings will be returned
217
+ # Reads a Thrift Binary (Thrift String without encoding). All Strings will be returned
208
218
  # with an Encoding of BINARY.
209
219
  #
210
220
  # Returns a String.
@@ -212,6 +222,13 @@ module Thrift
212
222
  raise NotImplementedError
213
223
  end
214
224
 
225
+ # Reads a UUID as 16 bytes and returns it as a string.
226
+ #
227
+ # Returns a String (e.g. "550e8400-e29b-41d4-a716-446655440000").
228
+ def read_uuid
229
+ raise NotImplementedError
230
+ end
231
+
215
232
  # Writes a field based on the field information, field ID and value.
216
233
  #
217
234
  # field_info - A Hash containing the definition of the field:
@@ -251,9 +268,9 @@ module Thrift
251
268
  #
252
269
  # Returns nothing.
253
270
  def write_type(field_info, value)
254
- # if field_info is a Fixnum, assume it is a Thrift::Types constant
271
+ # if field_info is a Integer, assume it is a Thrift::Types constant
255
272
  # convert it into a field_info Hash for backwards compatibility
256
- if field_info.is_a? Fixnum
273
+ if field_info.is_a? Integer
257
274
  field_info = {:type => field_info}
258
275
  end
259
276
 
@@ -276,6 +293,8 @@ module Thrift
276
293
  else
277
294
  write_string(value)
278
295
  end
296
+ when Types::UUID
297
+ write_uuid(value)
279
298
  when Types::STRUCT
280
299
  value.write(self)
281
300
  else
@@ -291,9 +310,9 @@ module Thrift
291
310
  #
292
311
  # Returns the value read; object type varies based on field_info[:type].
293
312
  def read_type(field_info)
294
- # if field_info is a Fixnum, assume it is a Thrift::Types constant
313
+ # if field_info is a Integer, assume it is a Thrift::Types constant
295
314
  # convert it into a field_info Hash for backwards compatibility
296
- if field_info.is_a? Fixnum
315
+ if field_info.is_a? Integer
297
316
  field_info = {:type => field_info}
298
317
  end
299
318
 
@@ -316,12 +335,15 @@ module Thrift
316
335
  else
317
336
  read_string
318
337
  end
338
+ when Types::UUID
339
+ read_uuid
319
340
  else
320
341
  raise NotImplementedError
321
342
  end
322
343
  end
323
344
 
324
- def skip(type)
345
+ def skip(type, max_depth = 64)
346
+ raise ProtocolException.new(ProtocolException::DEPTH_LIMIT, 'Maximum skip depth exceeded') if max_depth <= 0
325
347
  case type
326
348
  when Types::BOOL
327
349
  read_bool
@@ -337,39 +359,48 @@ module Thrift
337
359
  read_double
338
360
  when Types::STRING
339
361
  read_string
362
+ when Types::UUID
363
+ read_uuid
340
364
  when Types::STRUCT
341
365
  read_struct_begin
342
366
  while true
343
367
  name, type, id = read_field_begin
344
368
  break if type == Types::STOP
345
- skip(type)
369
+ skip(type, max_depth - 1)
346
370
  read_field_end
347
371
  end
348
372
  read_struct_end
349
373
  when Types::MAP
350
374
  ktype, vtype, size = read_map_begin
375
+ validate_container_size(size)
351
376
  size.times do
352
- skip(ktype)
353
- skip(vtype)
377
+ skip(ktype, max_depth - 1)
378
+ skip(vtype, max_depth - 1)
354
379
  end
355
380
  read_map_end
356
381
  when Types::SET
357
382
  etype, size = read_set_begin
383
+ validate_container_size(size)
358
384
  size.times do
359
- skip(etype)
385
+ skip(etype, max_depth - 1)
360
386
  end
361
387
  read_set_end
362
388
  when Types::LIST
363
389
  etype, size = read_list_begin
390
+ validate_container_size(size)
364
391
  size.times do
365
- skip(etype)
392
+ skip(etype, max_depth - 1)
366
393
  end
367
394
  read_list_end
368
395
  else
369
396
  raise ProtocolException.new(ProtocolException::INVALID_DATA, 'Invalid data')
370
397
  end
371
398
  end
372
-
399
+
400
+ def validate_container_size(size)
401
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
402
+ end
403
+
373
404
  def to_s
374
405
  "#{trans.to_s}"
375
406
  end
@@ -379,7 +410,7 @@ module Thrift
379
410
  def get_protocol(trans)
380
411
  raise NotImplementedError
381
412
  end
382
-
413
+
383
414
  def to_s
384
415
  "base"
385
416
  end
@@ -1,4 +1,5 @@
1
- #
1
+ # frozen_string_literal: true
2
+ #
2
3
  # Licensed to the Apache Software Foundation (ASF) under one
3
4
  # or more contributor license agreements. See the NOTICE file
4
5
  # distributed with this work for additional information
@@ -6,26 +7,34 @@
6
7
  # to you under the Apache License, Version 2.0 (the
7
8
  # "License"); you may not use this file except in compliance
8
9
  # with the License. You may obtain a copy of the License at
9
- #
10
+ #
10
11
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
+ #
12
13
  # Unless required by applicable law or agreed to in writing,
13
14
  # software distributed under the License is distributed on an
14
15
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
16
  # KIND, either express or implied. See the License for the
16
17
  # specific language governing permissions and limitations
17
18
  # under the License.
18
- #
19
+ #
19
20
 
20
21
  module Thrift
21
22
  class BinaryProtocol < BaseProtocol
22
23
  VERSION_MASK = 0xffff0000
23
24
  VERSION_1 = 0x80010000
24
25
  TYPE_MASK = 0x000000ff
25
-
26
+ BYTE_MIN = -2**7
27
+ BYTE_MAX = 2**7 - 1
28
+ I16_MIN = -2**15
29
+ I16_MAX = 2**15 - 1
30
+ I32_MIN = -2**31
31
+ I32_MAX = 2**31 - 1
32
+ I64_MIN = -2**63
33
+ I64_MAX = 2**63 - 1
34
+
26
35
  attr_reader :strict_read, :strict_write
27
36
 
28
- def initialize(trans, strict_read=true, strict_write=true)
37
+ def initialize(trans, strict_read = true, strict_write = true)
29
38
  super(trans)
30
39
  @strict_read = strict_read
31
40
  @strict_write = strict_write
@@ -36,11 +45,10 @@ module Thrift
36
45
  end
37
46
 
38
47
  def write_message_begin(name, type, seqid)
39
- # this is necessary because we added (needed) bounds checking to
40
- # write_i32, and 0x80010000 is too big for that.
41
48
  if strict_write
42
- write_i16(VERSION_1 >> 16)
43
- write_i16(type)
49
+ raise ::TypeError, 'integer argument expected' unless type.is_a?(Integer)
50
+ raise RangeError if type < BYTE_MIN || type > BYTE_MAX
51
+ trans.write([VERSION_1 | type].pack('N'))
44
52
  write_string(name)
45
53
  write_i32(seqid)
46
54
  else
@@ -64,17 +72,17 @@ module Thrift
64
72
  def write_map_begin(ktype, vtype, size)
65
73
  write_byte(ktype)
66
74
  write_byte(vtype)
67
- write_i32(size)
75
+ write_i32_size(size)
68
76
  end
69
77
 
70
78
  def write_list_begin(etype, size)
71
79
  write_byte(etype)
72
- write_i32(size)
80
+ write_i32_size(size)
73
81
  end
74
82
 
75
83
  def write_set_begin(etype, size)
76
84
  write_byte(etype)
77
- write_i32(size)
85
+ write_i32_size(size)
78
86
  end
79
87
 
80
88
  def write_bool(bool)
@@ -82,40 +90,57 @@ module Thrift
82
90
  end
83
91
 
84
92
  def write_byte(byte)
85
- raise RangeError if byte < -2**31 || byte >= 2**32
93
+ raise 'nil argument not allowed!' if byte.nil?
94
+ raise ::TypeError, 'integer argument expected' unless byte.is_a?(Integer)
95
+ raise RangeError if byte < BYTE_MIN || byte > BYTE_MAX
86
96
  trans.write([byte].pack('c'))
87
97
  end
88
98
 
89
99
  def write_i16(i16)
100
+ raise 'nil argument not allowed!' if i16.nil?
101
+ raise ::TypeError, 'integer argument expected' unless i16.is_a?(Integer)
102
+ raise RangeError if i16 < I16_MIN || i16 > I16_MAX
90
103
  trans.write([i16].pack('n'))
91
104
  end
92
105
 
93
106
  def write_i32(i32)
94
- raise RangeError if i32 < -2**31 || i32 >= 2**31
107
+ raise 'nil argument not allowed!' if i32.nil?
108
+ raise ::TypeError, 'integer argument expected' unless i32.is_a?(Integer)
109
+ raise RangeError if i32 < I32_MIN || i32 > I32_MAX
95
110
  trans.write([i32].pack('N'))
96
111
  end
97
112
 
98
113
  def write_i64(i64)
99
- raise RangeError if i64 < -2**63 || i64 >= 2**64
114
+ raise 'nil argument not allowed!' if i64.nil?
115
+ raise ::TypeError, 'integer argument expected' unless i64.is_a?(Integer)
116
+ raise RangeError if i64 < I64_MIN || i64 > I64_MAX
100
117
  hi = i64 >> 32
101
118
  lo = i64 & 0xffffffff
102
119
  trans.write([hi, lo].pack('N2'))
103
120
  end
104
121
 
105
122
  def write_double(dub)
123
+ raise 'nil argument not allowed!' if dub.nil?
106
124
  trans.write([dub].pack('G'))
107
125
  end
108
126
 
109
127
  def write_string(str)
128
+ raise 'nil argument not allowed!' if str.nil?
110
129
  buf = Bytes.convert_to_utf8_byte_buffer(str)
111
130
  write_binary(buf)
112
131
  end
113
132
 
114
133
  def write_binary(buf)
115
- write_i32(buf.bytesize)
134
+ raise 'nil argument not allowed!' if buf.nil?
135
+ write_i32_size(buf.bytesize)
116
136
  trans.write(buf)
117
137
  end
118
138
 
139
+ def write_uuid(uuid)
140
+ UUID.validate_uuid!(uuid)
141
+ trans.write(UUID.uuid_bytes(uuid))
142
+ end
143
+
119
144
  def read_message_begin
120
145
  version = read_i32
121
146
  if version < 0
@@ -153,18 +178,21 @@ module Thrift
153
178
  ktype = read_byte
154
179
  vtype = read_byte
155
180
  size = read_i32
181
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
156
182
  [ktype, vtype, size]
157
183
  end
158
184
 
159
185
  def read_list_begin
160
186
  etype = read_byte
161
187
  size = read_i32
188
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
162
189
  [etype, size]
163
190
  end
164
191
 
165
192
  def read_set_begin
166
193
  etype = read_byte
167
194
  size = read_i32
195
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size') unless size >= 0
168
196
  [etype, size]
169
197
  end
170
198
 
@@ -224,19 +252,36 @@ module Thrift
224
252
 
225
253
  def read_binary
226
254
  size = read_i32
227
- trans.read_all(size)
255
+ if size >= 0
256
+ trans.read_all(size)
257
+ else
258
+ raise ProtocolException.new(ProtocolException::NEGATIVE_SIZE, 'Negative size')
259
+ end
260
+ end
261
+
262
+ def read_uuid
263
+ UUID.uuid_from_bytes(trans.read_all(16))
228
264
  end
229
-
265
+
230
266
  def to_s
231
267
  "binary(#{super.to_s})"
232
268
  end
269
+
270
+ private
271
+
272
+ def write_i32_size(size)
273
+ raise 'nil argument not allowed!' if size.nil?
274
+ raise ::TypeError, 'integer argument expected' unless size.is_a?(Integer)
275
+ raise RangeError if size < 0 || size > I32_MAX
276
+ trans.write([size].pack('N'))
277
+ end
233
278
  end
234
279
 
235
280
  class BinaryProtocolFactory < BaseProtocolFactory
236
281
  def get_protocol(trans)
237
282
  return Thrift::BinaryProtocol.new(trans)
238
283
  end
239
-
284
+
240
285
  def to_s
241
286
  "binary"
242
287
  end
@@ -1,4 +1,5 @@
1
- #
1
+ # frozen_string_literal: true
2
+ #
2
3
  # Licensed to the Apache Software Foundation (ASF) under one
3
4
  # or more contributor license agreements. See the NOTICE file
4
5
  # distributed with this work for additional information
@@ -6,20 +7,20 @@
6
7
  # to you under the Apache License, Version 2.0 (the
7
8
  # "License"); you may not use this file except in compliance
8
9
  # with the License. You may obtain a copy of the License at
9
- #
10
+ #
10
11
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
+ #
12
13
  # Unless required by applicable law or agreed to in writing,
13
14
  # software distributed under the License is distributed on an
14
15
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
16
  # KIND, either express or implied. See the License for the
16
17
  # specific language governing permissions and limitations
17
18
  # under the License.
18
- #
19
+ #
19
20
 
20
21
  =begin
21
22
  The only change required for a transport to support BinaryProtocolAccelerated is to implement 2 methods:
22
- * borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport,
23
+ * borrow(size), which takes an optional argument and returns atleast _size_ bytes from the transport,
23
24
  or the default buffer size if no argument is given
24
25
  * consume!(size), which removes size bytes from the front of the buffer
25
26