ruby-protocol-buffers 1.2.1 → 1.2.2

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.
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