Skip to content

Commit 9e74c0b

Browse files
authored
Merge pull request #332 from Shopify/infinite-symbol-recusrsion
Fix an infinite recursion issue when registering a Symbol type with a `nil` packer
2 parents 1ac6811 + d7e4783 commit 9e74c0b

6 files changed

Lines changed: 23 additions & 6 deletions

File tree

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
* Fix an infinite recursion issue when registering a Symbol type with a `nil` packer.
2+
13
2023-03-29 1.7.0:
24

35
* Fix a possible double-free issue when GC triggers inside `_msgpack_rmem_alloc2`.

ext/java/org/msgpack/jruby/ExtensionRegistry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ public boolean isRecursive() {
141141
}
142142

143143
public boolean hasPacker() {
144-
return packerProc != null;
144+
return packerProc != null && !packerProc.isNil();
145145
}
146146

147147
public boolean hasUnpacker() {
148-
return unpackerProc != null;
148+
return unpackerProc != null && !unpackerProc.isNil();
149149
}
150150

151151
public IRubyObject getPackerProc() {

ext/java/org/msgpack/jruby/Factory.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,13 @@ public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args) {
100100
if (args[args.length - 1] instanceof RubyHash) {
101101
options = (RubyHash) args[args.length - 1];
102102
packerArg = options.fastARef(runtime.newSymbol("packer"));
103+
if (packerArg != null && packerArg.isNil()) {
104+
packerArg = null;
105+
}
103106
unpackerArg = options.fastARef(runtime.newSymbol("unpacker"));
107+
if (unpackerArg != null && unpackerArg.isNil()) {
108+
unpackerArg = null;
109+
}
104110
IRubyObject optimizedSymbolsParsingArg = options.fastARef(runtime.newSymbol("optimized_symbols_parsing"));
105111
if (optimizedSymbolsParsingArg != null && optimizedSymbolsParsingArg.isTrue()) {
106112
throw runtime.newArgumentError("JRuby implementation does not support the optimized_symbols_parsing option");
@@ -147,7 +153,7 @@ public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args) {
147153

148154
extensionRegistry.put(extModule, (int) typeId, recursive, packerProc, packerArg, unpackerProc, unpackerArg);
149155

150-
if (extModule == runtime.getSymbol()) {
156+
if (extModule == runtime.getSymbol() && !packerProc.isNil()) {
151157
hasSymbolExtType = true;
152158
}
153159

ext/java/org/msgpack/jruby/Packer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Blo
128128

129129
registry.put(extModule, (int) typeId, false, proc, arg, null, null);
130130

131-
if (extModule == runtime.getSymbol()) {
131+
if (extModule == runtime.getSymbol() && !proc.isNil()) {
132132
encoder.hasSymbolExtType = true;
133133
}
134134

ext/msgpack/factory_class.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,12 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
222222
unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
223223
break;
224224
case 3:
225-
/* register_type(0x7f, Time, packer: proc-like, unapcker: proc-like) */
225+
/* register_type(0x7f, Time, packer: proc-like, unpacker: proc-like) */
226226
options = argv[2];
227227
if(rb_type(options) != T_HASH) {
228228
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
229229
}
230+
230231
packer_arg = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
231232
unpacker_arg = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
232233
break;
@@ -266,7 +267,9 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
266267
}
267268

268269
if(ext_module == rb_cSymbol) {
269-
fc->has_symbol_ext_type = true;
270+
if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
271+
fc->has_symbol_ext_type = true;
272+
}
270273
if(RTEST(options) && RTEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
271274
fc->optimized_symbol_ext_type = true;
272275
}

spec/factory_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ class MyType2 < MyType
249249
my.b.should == 2
250250
end
251251

252+
it 'handles Symbol type with `packer: nil`' do
253+
factory = MessagePack::Factory.new
254+
factory.register_type(0x00, Symbol, packer: nil)
255+
expect(factory.load(factory.dump(:foo))).to be == "foo"
256+
end
257+
252258
describe "registering multiple ext type for the same class" do
253259
let(:payload) do
254260
factory = MessagePack::Factory.new

0 commit comments

Comments
 (0)