Skip to content

Commit

Permalink
Merge pull request #122 from localshred/bj/backport_string_field_issues
Browse files Browse the repository at this point in the history
Backport string field encode fixes from 2.8.x
  • Loading branch information
localshred committed Sep 17, 2013
2 parents 1a76628 + c6fa28d commit 93ae5db
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 13 deletions.
14 changes: 8 additions & 6 deletions lib/protobuf/field/bytes_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ def acceptable?(val)
end

def decode(bytes)
bytes.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
bytes
bytes_to_decode = bytes.dup
bytes_to_decode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
bytes_to_decode
end

def define_setter
Expand All @@ -46,11 +47,12 @@ def define_setter
end

def encode(value)
value = value.serialize_to_string if value.is_a?(::Protobuf::Message)
value.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
value_to_encode = value.dup
value_to_encode = value.serialize_to_string if value.is_a?(::Protobuf::Message)
value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)

string_size = ::Protobuf::Field::VarintField.encode(value.size)
string_size << value
string_size = ::Protobuf::Field::VarintField.encode(value_to_encode.size)
string_size << value_to_encode
end

def wire_type
Expand Down
15 changes: 8 additions & 7 deletions lib/protobuf/field/string_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ class StringField < BytesField
ENCODING = 'UTF-8'.freeze

def decode(bytes)
bytes.force_encoding(::Protobuf::Field::StringField::ENCODING)
bytes
bytes_to_decode = bytes.dup
bytes_to_decode.force_encoding(::Protobuf::Field::StringField::ENCODING)
bytes_to_decode
end

def encode(value)
# TODO: make replace character configurable?
value.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
value.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
value_to_encode = value.dup
value_to_encode.encode!(::Protobuf::Field::StringField::ENCODING, :invalid => :replace, :undef => :replace, :replace => "")
value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)

string_size = ::Protobuf::Field::VarintField.encode(value.size)
string_size << value
string_size = ::Protobuf::Field::VarintField.encode(value_to_encode.size)
string_size << value_to_encode
end
end
end
Expand Down
46 changes: 46 additions & 0 deletions spec/lib/protobuf/field/string_field_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# encoding: utf-8

require 'spec_helper'

describe ::Protobuf::Field::StringField do

describe '#encode' do
context 'when a repeated string field contains frozen strings' do
it 'does not raise an encoding error' do
expect {
frozen_strings = [ "foo".freeze, "bar".freeze, "baz".freeze ]
::Test::ResourceFindRequest.new(:name => 'resource', :widgets => frozen_strings).serialize_to_string
}.not_to raise_error
end
end

context 'when a repeated bytes field contains frozen strings' do
it 'does not raise an encoding error' do
expect {
frozen_strings = [ "foo".freeze, "bar".freeze, "baz".freeze ]
::Test::ResourceFindRequest.new(:name => 'resource', :widget_bytes => frozen_strings).serialize_to_string
}.not_to raise_error
end
end

it 'does not alter string values after encoding multiple times' do
source_string = "foo"
proto = ::Test::Resource.new(:name => source_string)
proto.serialize_to_string
proto.name.should eq source_string
proto.serialize_to_string
proto.name.should eq source_string
end

it 'does not alter unicode string values after encoding multiple times' do
source_string = "¢"
proto = ::Test::Resource.new(:name => source_string)
proto.serialize_to_string
proto.name.should eq source_string
proto.serialize_to_string
proto.name.should eq source_string
end
end


end

0 comments on commit 93ae5db

Please sign in to comment.