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 +1 -1
- data/lib/protocol_buffers/runtime/encoder.rb +9 -5
- data/lib/protocol_buffers/runtime/field.rb +15 -2
- data/lib/protocol_buffers/runtime/message.rb +12 -3
- data/spec/negative_int32_spec.rb +33 -0
- data/spec/nil_bugs_spec.rb +24 -0
- data/spec/runtime_spec.rb +10 -0
- data/spec/spec_helper.rb +92 -0
- data/spec/unicode_string_spec.rb +33 -0
- metadata +11 -7
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.2
|
@@ -1,12 +1,16 @@
|
|
1
1
|
module ProtocolBuffers
|
2
2
|
|
3
|
-
class EncodeError < StandardError
|
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
|
-
|
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.
|
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
|
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<<
|
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
|
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:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 1.2.
|
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:
|
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
|
-
|
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.
|
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
|