Skip to content

Commit

Permalink
Do not intern extension type strings
Browse files Browse the repository at this point in the history
Fix: msgpack#248 (comment)

Extensions might not expect it, and it's unlikely that they'll be kept
as is as binary strings anyway.
  • Loading branch information
byroot committed Feb 10, 2022
1 parent 98a01de commit 3c66561
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
16 changes: 6 additions & 10 deletions ext/msgpack/unpacker.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,21 +291,17 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
ret = object_complete_symbol(uk, symbol);
} else {
/* don't use zerocopy for hash keys but get a frozen string directly
* because rb_hash_aset freezes keys and it causes copying */
bool will_freeze = uk->freeze || is_reading_map_key(uk);
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
bool will_freeze = uk->freeze;
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
/* don't use zerocopy for hash keys but get a frozen string directly
* because rb_hash_aset freezes keys and it causes copying */
will_freeze = will_freeze || is_reading_map_key(uk);
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
ret = object_complete(uk, string);
} else {
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
ret = object_complete_ext(uk, raw_type, string);
}

# if !HASH_ASET_DEDUPE
if(will_freeze) {
rb_obj_freeze(string);
}
# endif
}
uk->reading_raw_remaining = 0;
return ret;
Expand Down
12 changes: 10 additions & 2 deletions spec/factory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,8 @@ def to_msgpack_ext
end

describe 'the special treatment of symbols with ext type' do
def roundtrip(object)
subject.load(subject.dump(object))
def roundtrip(object, options = nil)
subject.load(subject.dump(object), options)
end

context 'using the optimized symbol unpacker' do
Expand Down Expand Up @@ -333,6 +333,14 @@ def roundtrip(object)
expect(roundtrip(:symbol)).to be :symbol
end

it 'works with hash keys' do
expect(roundtrip(symbol: 1)).to be == { symbol: 1 }
end

it 'works with frozen: true option' do
expect(roundtrip(:symbol, freeze: true)).to be :symbol
end

it 'preserves encoding for ASCII symbols' do
expect(:symbol.encoding).to be Encoding::US_ASCII
expect(roundtrip(:symbol)).to be :symbol
Expand Down

0 comments on commit 3c66561

Please sign in to comment.