Guard packerProc against a missing :packer key on JRuby - #406
Merged
Conversation
RubyHash#fastARef returns Java null for an absent key, so registering a Symbol type with only an :unpacker raised NullPointerException. ExtensionEntry.hasPacker already guards the same value this way.
Member
|
Thanks for the fix, but please tune down your agent. A wall of text like this for a one liner fix is a huge pain. |
byroot
approved these changes
Sep 11, 2026
Contributor
Author
|
Fair, and noted — I will keep the body proportional to the diff from here. Thanks for merging. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On JRuby, registering a
Symboltype with only an unpacker raises:CRuby accepts the same call and round-trips (
factory.load(factory.dump(:foo))is"foo"). Registering any other module the same way works on both.Cause
RubyHash#fastARefreturns Javanullfor an absent key, where CRuby'srb_hash_arefreturnsQnil.Factory.java:115is the one place inregisterTypeInternalthat dereferences afastARefresult without a null check:The other two results in the same method are both guarded —
recursiveExtensionArg != null && ...(Factory.java:107) andoversizedIntegerExtensionArg != null && ...(Factory.java:120).So is this same value, everywhere else it is read.
ExtensionEntry.hasPacker(ExtensionRegistry.java:139-141) guards it with exactly the expression this change uses:That matters beyond style:
extensionRegistry.put(...)on the line directly above already receives this samenulland handles it, which is whyhasPackeris written that way. Only thehasSymbolExtTypeassignment was left unguarded.The CRuby counterpart reaches the same result through
Qnil:fc->has_symbol_ext_type = NIL_P(options) || RTEST(packer_proc);(ext/msgpack/factory_class.c:237) — an absent:packergivesQnil,RTESTis false, andhas_symbol_ext_typeends up false. With this change JRuby agrees.This is not new in #403; that PR moved
!packerProc.isNil()from theifcondition into the assignment, and the dereference was present in both forms. It is just the most recent commit on the line.Why packer-less registration is a shape worth supporting
registered_typeshas a dedicated "unpacker definition only" branch (lib/msgpack/factory.rb:64-67), and #332 was specifically about making a Symbol type with anilpacker work. This is the same shape with the key omitted rather than set tonil.Verification
Built and run in Docker. The Java sources were compiled with
javacand re-jarred for every row, and I md5'd the jar each time to be sure the rebuild actually reached the runtime.masterfactory_spec.rb:276)factory_spec.rb:276)packerProc != nullonly, dropping theisNil()halffactory_spec.rb:270)The last row is the useful one: dropping the
isNil()half breaks the existinghandles Symbol type withpacker: nil`` example from #332, so both halves of the expression are doing work and neither test is decorative.Full suites, each with the pattern
Rakefile:57-61selects for that platform:spec/{,cruby/}*_spec.rb)spec/{,jruby/}*_spec.rb)The C extension is untouched, so the
valgrindjob has no new path to cover.Disclosure: I used Claude (an AI assistant) while preparing this change. Every result above I ran and verified myself.