mruby-socket: reject a big integer getaddrinfo hint instead of ignoring it - #7118
Merged
Conversation
…ng it `Addrinfo.getaddrinfo` converts its `family`, `socktype` and `protocol` hints only under `mrb_integer_p`, which asks about representation rather than class. Where `mruby-bigint` is built in, a hint too wide for `mrb_int` arrives as `MRB_TT_BIGINT`, the conversion is skipped, and the field keeps its zeroed default: the caller asked for something unrepresentable and got an unhinted lookup back. That inverts the narrowing check added in mruby#6960, since a value that fits `mrb_int` but not C `int` raises while a larger one passes silently: ```ruby Addrinfo.getaddrinfo("localhost", nil, 2 ** 40) # RangeError Addrinfo.getaddrinfo("localhost", nil, 2 ** 70) # AF_UNSPEC results ``` Widen the guard to `mrb_bigint_p` as well and hand the value itself to `getaddrinfo_hint`. A big integer outgrows `mrb_int`, so it never fits a C `int` either, and it can be reported with the same message as any other out of range hint. `mrb_bigint_p` is `FALSE` without `MRB_USE_BIGINT`, so a build without bigint keeps the code it had. `flags` is unaffected, because `mrb_get_args` already rejects a big integer for its `i` specifier; it moves to the new signature only to keep one entry point. The added test builds its shift width from a variable, because a literal wide shift is constant folded and the fold fails where bigint is absent, which would drop every test in the file.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough
ChangesAddrinfo hint validation
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Addrinfo.getaddrinfoconverts itsfamily,socktypeandprotocolhints only undermrb_integer_p, which asks about representation rather than class. Wheremruby-bigintis built in, a hint too wide formrb_intarrives asMRB_TT_BIGINT, the conversion is skipped, and the field keeps the default fromstruct addrinfo hints = {0}. The caller asked for something unrepresentable and got an unhinted lookup back.That inverts the narrowing check added in #6960: a value that fits
mrb_intbut not Cintraises, while a larger one passes silently. On the default 64 bit build, which carries bigint:It is not specific to
MRB_INT32; any build carryingmruby-biginthas it, andMRB_INT32only lowers the threshold to2 ** 32.Change
getaddrinfo_hintnow takes themrb_valueand rejects a big integer before reading it, so an out of range hint is reported the same way whatever its representation. The three call sites testmrb_integer_p(v) || mrb_bigint_p(v).mrb_bigint_pisFALSEwithoutMRB_USE_BIGINT, so a build without bigint compiles to what it had before.flagsis unaffected, becausemrb_get_argsalready raisesRangeErrorfor a big integer passed to itsispecifier. It moves to the new signature only to keep one entry point.Values of other classes are still ignored rather than rejected, as before; narrowing that is a separate question from this one.
Test
The new assertion fails on master (
KO: 1) and passes with the change. Its shift width comes from a variable because a literal wide shift is constant folded, and the fold fails where bigint is absent.KO: 0, new test runsMRB_INT32with bigintKO: 0, file not loadedMRB_INT32without bigint,mruby-socketaddedKO: 0, file not loadedThe two
MRB_INT32builds do not reach this file: the literal1 << 40in the assertion above the new one folds to a value the 32 bit VM cannot load, so the whole file is dropped without a failure. That is the subject of #7117, and it is left alone here so the two changes do not touch the same lines. Applying that fix locally on top of this branch gives 2147 (KO: 0, new test runs and passes) with bigint and 1785 (KO: 0, new test skips) without it.Summary by CodeRabbit
RangeErrorinstead of being processed incorrectly.