Skip to content

Commit

Permalink
Avoid encoding issues when sending strings to Redis.
Browse files Browse the repository at this point in the history
  • Loading branch information
djanowski authored and shingara committed Aug 6, 2011
1 parent aca3fbf commit 113d6e6
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
14 changes: 12 additions & 2 deletions lib/redis/store/marshalling.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ class Redis
class Store < self
module Marshalling
def set(key, value, options = nil)
_marshal(value, options) { |value| super key, value, options }
_marshal(value, options) { |value| super encode(key), encode(value), options }
end

def setnx(key, value, options = nil)
_marshal(value, options) { |value| super key, value, options }
_marshal(value, options) { |value| super encode(key), encode(value), options }
end

def get(key, options = nil)
Expand Down Expand Up @@ -36,6 +36,16 @@ def marshal?(options)
def unmarshal?(result, options)
result && result.size > 0 && marshal?(options)
end

if defined?(Encoding)
def encode(string)
string.to_s.force_encoding(Encoding::BINARY)
end
else
def encode(string)
string
end
end
end
end
end
36 changes: 36 additions & 0 deletions spec/redis/store/marshalling_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,41 @@
rabbit2.should == "\004\bU:\017OpenStruct{\006:\ncolor\"\nwhite"
end
end

describe "binary safety" do
it "should marshal objects" do
utf8_key = [51339].pack("U*")
ascii_rabbit = OpenStruct.new(:name => [128].pack("C*"))

@store.set(utf8_key, ascii_rabbit)
@store.get(utf8_key).should === ascii_rabbit
end

it "should get and set raw values" do
utf8_key = [51339].pack("U*")
ascii_string = [128].pack("C*")

@store.set(utf8_key, ascii_string, :raw => true)
@store.get(utf8_key, :raw => true).bytes.to_a === ascii_string.bytes.to_a
end

it "should marshal objects on setnx" do
utf8_key = [51339].pack("U*")
ascii_rabbit = OpenStruct.new(:name => [128].pack("C*"))

@store.del(utf8_key)
@store.setnx(utf8_key, ascii_rabbit)
@store.get(utf8_key).should === ascii_rabbit
end

it "should get and set raw values on setnx" do
utf8_key = [51339].pack("U*")
ascii_string = [128].pack("C*")

@store.del(utf8_key)
@store.setnx(utf8_key, ascii_string, :raw => true)
@store.get(utf8_key, :raw => true).bytes.to_a === ascii_string.bytes.to_a
end
end if defined?(Encoding)
end

0 comments on commit 113d6e6

Please sign in to comment.