ruby-protocol-buffers 1.2.1 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.1
1
+ 1.2.2
@@ -1,12 +1,16 @@
1
1
  module ProtocolBuffers
2
2
 
3
- class EncodeError < StandardError; end
3
+ class EncodeError < StandardError
4
+ attr_reader :invalid_field
5
+
6
+ def initialize(invalid_field)
7
+ @invalid_field = invalid_field
8
+ end
9
+ end
4
10
 
5
11
  module Encoder # :nodoc: all
6
12
  def self.encode(io, message)
7
- unless message.valid?
8
- raise(EncodeError, "invalid message")
9
- end
13
+ message.validate!
10
14
 
11
15
  message.fields.each do |tag, field|
12
16
  next unless message.value_for_tag?(tag)
@@ -40,7 +44,7 @@ module ProtocolBuffers
40
44
  when 1, 5 # FIXED64, FIXED32
41
45
  io.write(serialized)
42
46
  when 2 # LENGTH_DELIMITED
43
- Varint.encode(io, serialized.length)
47
+ Varint.encode(io, serialized.bytesize)
44
48
  io.write(serialized)
45
49
  when 3, 4 # deprecated START_GROUP/END_GROUP types
46
50
  raise(EncodeError, "groups are deprecated and unsupported")
@@ -142,7 +142,7 @@ module ProtocolBuffers
142
142
  def #{name}=(value)
143
143
  field = fields[#{tag}]
144
144
  if value.nil?
145
- @set_fields.delete_at(#{tag})
145
+ @set_fields[#{tag}] = false
146
146
  @#{name} = field.default_value
147
147
  else
148
148
  field.check_valid(value)
@@ -263,6 +263,18 @@ module ProtocolBuffers
263
263
  #
264
264
  # Maybe we just punt on this except in Ruby 1.9 where we can rely on the
265
265
  # language ensuring the string is always UTF-8?
266
+
267
+ def deserialize(value)
268
+ # To get bytes, the value was being read as ASCII. Ruby 1.9 stores an encoding
269
+ # with its strings, and they were getting returned with Encoding ASCII-8BIT.
270
+ # Protobuffers are supposed to only return UTF-8 strings. This attempts to
271
+ # force the encoding to UTF-8 if on Ruby 1.9 (force_encoding is defined on String).
272
+ read_value = value.read.to_s
273
+ if read_value.respond_to?("force_encoding")
274
+ read_value.force_encoding("UTF-8")
275
+ end
276
+ read_value
277
+ end
266
278
  end
267
279
 
268
280
  class NumericField < Field
@@ -301,8 +313,9 @@ module ProtocolBuffers
301
313
 
302
314
  class SignedVarintField < VarintField
303
315
  def deserialize(value)
316
+ # This is to handle negatives...they are always 64-bit
304
317
  if value > max
305
- value - (1<<bits)
318
+ value - (1<<64)
306
319
  else
307
320
  value
308
321
  end
@@ -458,16 +458,25 @@ module ProtocolBuffers
458
458
  self.class.valid?(self)
459
459
  end
460
460
 
461
- def self.valid?(message)
461
+ def self.valid?(message, raise_exception=false)
462
462
  return true unless @has_required_field
463
463
 
464
464
  fields.each do |tag, field|
465
- if field.otype == :required
466
- return false unless message.value_for_tag?(tag)
465
+ if field.otype == :required && !message.value_for_tag?(tag)
466
+ return false unless raise_exception
467
+ raise(ProtocolBuffers::EncodeError.new(field), "Required field '#{field.name}' is invalid")
467
468
  end
468
469
  end
469
470
  end
470
471
 
472
+ def validate!
473
+ self.class.validate!(self)
474
+ end
475
+
476
+ def self.validate!(message)
477
+ valid?(message, true)
478
+ end
479
+
471
480
  def remember_unknown_field(tag_int, value)
472
481
  @unknown_fields || @unknown_fields = []
473
482
  @unknown_fields << [tag_int, value]
@@ -0,0 +1,33 @@
1
+ # Tests for issues with decoding negative int32 fields
2
+
3
+ # By Mark Herman <mherman@iseatz.com> based on code from
4
+ # Tom Zetty <tzetty@iseatz.com>
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
7
+
8
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
9
+ require 'protocol_buffers'
10
+
11
+ describe "Testing for decode errors for negative int32 fields" do
12
+ # These should fail without the int32 negative handling fix
13
+ it "should return -1 given -1" do
14
+ (validate_pbr(SignedIntTest, -1, true)).should be_true
15
+ end
16
+
17
+ it "should return -1111 given -1111" do
18
+ (validate_pbr(SignedIntTest, -1111, true)).should be_true
19
+ end
20
+
21
+ # These should pass with or without the negative handling fix
22
+ it "should return 1 given 1" do
23
+ (validate_pbr(SignedIntTest, 1, true)).should be_true
24
+ end
25
+
26
+ it "should return 0 given 0" do
27
+ (validate_pbr(SignedIntTest, 0, true)).should be_true
28
+ end
29
+
30
+ it "should return 100000 given 100000" do
31
+ (validate_pbr(SignedIntTest, 100000, true)).should be_true
32
+ end
33
+ end
@@ -0,0 +1,24 @@
1
+ # Tests for issues with handling of nil fields in protobuffers
2
+
3
+ # By Mark Herman <mherman@iseatz.com>
4
+
5
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
6
+
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
8
+ require 'protocol_buffers'
9
+
10
+ # Without the nil fix, assigning nil to a field would cause the encoder to
11
+ # start failing to encode fields.
12
+ describe "testing handling of nil assignments to protobuffers" do
13
+ it "should accept nil assignments into a single field without losing other data" do
14
+ # I will assign nil a couple of times and then test whether the protobuffer encodes at all
15
+ test_pb = NilTest.new
16
+ test_pb.test_field_1 = "test_value_1"
17
+ test_pb.test_field_2 = "test_value_2"
18
+
19
+ test_pb.test_field_1 = nil
20
+ test_pb.test_field_1 = nil
21
+
22
+ (test_pb.to_s.length > 0).should be_true
23
+ end
24
+ end
data/spec/runtime_spec.rb CHANGED
@@ -333,6 +333,16 @@ describe ProtocolBuffers, "runtime" do
333
333
  res1 = TehUnknown::MyResult.new(:field_2 => 'b')
334
334
 
335
335
  proc { res1.to_s }.should raise_error(ProtocolBuffers::EncodeError)
336
+
337
+ begin
338
+ res1.to_s
339
+ rescue Exception => e
340
+ e.invalid_field.name.should == :field_1
341
+ e.invalid_field.tag.should == 1
342
+ e.invalid_field.otype.should == :required
343
+ e.invalid_field.default_value.should == ''
344
+ end
345
+
336
346
  end
337
347
 
338
348
  it "enforces required fields on deserialization" do
data/spec/spec_helper.rb CHANGED
@@ -2,5 +2,97 @@ require 'protocol_buffers'
2
2
 
3
3
  require 'rspec'
4
4
 
5
+ # These are a couple of classes used by tests
6
+ class SignedIntTest < ::ProtocolBuffers::Message
7
+ required :int32, :test_member, 1
8
+ gen_methods! # new fields ignored after this point
9
+ end
10
+
11
+ class StringTest < ::ProtocolBuffers::Message
12
+ optional :string, :test_member, 1
13
+ gen_methods! # new fields ignored after this point
14
+ end
15
+
16
+ class NilTest < ::ProtocolBuffers::Message
17
+ optional :string, :test_field_1, 1
18
+ optional :string, :test_field_2, 2
19
+ gen_methods! # new fields ignored after this point
20
+ end
21
+
22
+ # klass should be derived from ::ProtocolBuffers::Message
23
+ # and have a member named test_member
24
+ # value is assigned to test member, then an encoding/parse cycle occurs
25
+ # rescues are reported
26
+
27
+ # suppress_output is meant for use in RSpec tests where output is not desired
28
+
29
+ # This function returns true if value == decoded proto value
30
+ def validate_pbr(klass, value, suppress_output = false)
31
+ unless suppress_output
32
+ puts
33
+ puts "Validate Pbr: class=#{klass.name}, value=#{value}"
34
+ puts " creating and encoding"
35
+ end
36
+
37
+ encode_pbr = klass.new
38
+ encode_pbr.test_member = value
39
+ encoded_string = encode_pbr.to_s
40
+
41
+ unless suppress_output
42
+ puts " encoded_string: #{to_hex_string encoded_string}"
43
+ puts " encoded length: #{encoded_string.length}"
44
+ puts " parsing encoded_string"
45
+ end
46
+
47
+ decode_pbr = nil;
48
+ begin
49
+ decode_pbr = klass.parse encoded_string
50
+ rescue Exception => e
51
+ # Exceptions always return false
52
+ unless suppress_output
53
+ puts e.message
54
+ puts " FAIL: RESCUE occured in #{klass.name}.parse"
55
+ end
56
+ return false
57
+ end
58
+
59
+ if decode_pbr
60
+ unless suppress_output
61
+ puts " decoded value: #{decode_pbr.test_member}"
62
+ puts " passed value: #{value}"
63
+ puts " decoded value <=> passed value = #{decode_pbr.test_member <=> value}"
64
+ end
65
+
66
+ if value.respond_to?("bytesize")
67
+ unless suppress_output
68
+ puts " decoded value bytesize: #{decode_pbr.test_member.bytesize}"
69
+ puts " passed value bytesize : #{value.bytesize}"
70
+ puts " decoded value inspect : #{decode_pbr.test_member.inspect}"
71
+ puts " passed value inspect : #{value.inspect}"
72
+ end
73
+
74
+ # Ruby 1.8 Strings don't have encodings
75
+ if decode_pbr.test_member.respond_to?("encoding")
76
+ unless suppress_output
77
+ puts " decoded value encoding: #{decode_pbr.test_member.encoding.name}"
78
+ puts " passed value encoding : #{value.encoding.name}"
79
+ end
80
+ end
81
+ end
82
+
83
+ unless suppress_output
84
+ puts " GOOD COMPARE" if decode_pbr.test_member == value
85
+ end
86
+
87
+ decode_pbr.test_member == value
88
+ end
89
+ end
90
+
91
+ def to_hex_string ss
92
+ yy = []
93
+ ss.each_byte { |b| yy << b.to_s(16) }
94
+ yy.join(' ')
95
+ end
96
+
5
97
  RSpec.configure do |config|
6
98
  end
@@ -0,0 +1,33 @@
1
+ # Tests for Unicode issues in protobuffer library.
2
+
3
+ # By Mark Herman <mherman@iseatz.com> based on code from
4
+ # Tom Zetty <tzetty@iseatz.com>
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
7
+
8
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
9
+ require 'protocol_buffers'
10
+
11
+ describe "Testing for bugs in Unicode encoding and decoding" do
12
+ # This should always pass
13
+ it "should return the input string given a regular string" do
14
+ validate_pbr(StringTest, "test_string", true).should be_true
15
+ end
16
+
17
+ # Encoding objects aren't defined in Ruby 1.8. This will only run on 1.9 or above.
18
+ # It should fail on Ruby 1.9 without the Unicode fix.
19
+ if ''.respond_to? "encoding"
20
+ it "should return the given UTF8 string" do
21
+ validate_pbr(StringTest, ''.encode(Encoding::UTF_8) + "utf8_rulz", true)
22
+ end
23
+ end
24
+
25
+ # This should pass in Ruby 1.8 with the Unicode fix, but it will know nothing of the encoding
26
+ # This should fail without the Unicode fix. The previous implementation was encoding
27
+ # with the character length rather than the byte length. It was also returning strings
28
+ # with their encoding set to ASCII. The new code forces it to UTF-8.
29
+ it "should return the given Unicode string" do
30
+ string_with_r = "(R) Char: \u00AE"
31
+ validate_pbr(StringTest, string_with_r, true).should be_true
32
+ end
33
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-protocol-buffers
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 1
10
- version: 1.2.1
9
+ - 2
10
+ version: 1.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian Palmer
@@ -17,8 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-10-01 00:00:00 -06:00
21
- default_executable:
20
+ date: 2012-01-16 00:00:00 Z
22
21
  dependencies:
23
22
  - !ruby/object:Gem::Dependency
24
23
  name: rspec
@@ -137,6 +136,8 @@ files:
137
136
  - ruby-protocol-buffers.gemspec
138
137
  - spec/compiler_spec.rb
139
138
  - spec/fields_spec.rb
139
+ - spec/negative_int32_spec.rb
140
+ - spec/nil_bugs_spec.rb
140
141
  - spec/proto_files/depends.proto
141
142
  - spec/proto_files/dotted_package.proto
142
143
  - spec/proto_files/featureful.proto
@@ -147,7 +148,7 @@ files:
147
148
  - spec/runtime_spec.rb
148
149
  - spec/spec.opts
149
150
  - spec/spec_helper.rb
150
- has_rdoc: true
151
+ - spec/unicode_string_spec.rb
151
152
  homepage: https://github.com/mozy/ruby-protocol-buffers
152
153
  licenses: []
153
154
 
@@ -177,13 +178,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
178
  requirements: []
178
179
 
179
180
  rubyforge_project:
180
- rubygems_version: 1.6.2
181
+ rubygems_version: 1.8.11
181
182
  signing_key:
182
183
  specification_version: 3
183
184
  summary: Ruby compiler and runtime for the google protocol buffers library.
184
185
  test_files:
185
186
  - spec/compiler_spec.rb
186
187
  - spec/fields_spec.rb
188
+ - spec/negative_int32_spec.rb
189
+ - spec/nil_bugs_spec.rb
187
190
  - spec/proto_files/depends.proto
188
191
  - spec/proto_files/dotted_package.proto
189
192
  - spec/proto_files/featureful.proto
@@ -194,3 +197,4 @@ test_files:
194
197
  - spec/runtime_spec.rb
195
198
  - spec/spec.opts
196
199
  - spec/spec_helper.rb
200
+ - spec/unicode_string_spec.rb