Skip to content

string.c: bound check mrb_str_byte_to_char before use - #7098

Merged
matz merged 1 commit into
mruby:masterfrom
takumin:string-byte-to-char-bounds
Aug 12, 2026
Merged

string.c: bound check mrb_str_byte_to_char before use#7098
matz merged 1 commit into
mruby:masterfrom
takumin:string-byte-to-char-bounds

Conversation

@takumin

@takumin takumin commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #7097, which promoted chars2bytes / bytes2chars to
mrb_str_char_to_byte / mrb_str_byte_to_char. This addresses a review
comment that arrived after the merge.

mrb_str_byte_to_char formed p + bi before testing the offset, so a byte
offset outside the string produced an out-of-bounds pointer, and the
single-byte and binary fast path returned that offset unchanged instead of
-1. Moving the bounds test to the top covers the fast path and the pointer
arithmetic alike, and the e < pivot test it replaces goes away.

The non-UTF-8 identity function gets the same test, so the documented
contract holds on every build: -1 when the offset lies outside the string,
and on UTF-8 builds also when it lands inside a multi-byte character. Without
this, the same call would answer differently depending on MRB_UTF8_STRING,
which is the opposite of what promoting these functions was for.

Every caller clamps the offset it passes today (str_rindex results,
str_index_str_by_char, and re_byte_to_char in mruby-regexp, which clamps
to RSTRING_LEN before calling), so no behavior changes. The check belongs
in the function now that it is internal API rather than a static confined to
string.c.

Testing

  • rake test with build_config/host-debug.rb (full-core, MRB_UTF8_STRING):
    mrbtest 2233 OK / 0 KO, bintest 116 OK.
  • rake test with the default config (byte strings, identity conversion):
    mrbtest 2032 OK / 0 KO, bintest 105 OK.

Summary by CodeRabbit

  • Bug Fixes

    • String byte-to-character conversion now rejects negative and out-of-range byte offsets consistently.
    • Invalid offsets return an error instead of producing unexpected character positions.
    • Non-UTF-8 conversions continue to behave as identity operations while enforcing valid bounds.
  • Documentation

    • Clarified the accepted offset range and behavior for non-UTF-8 strings.

The function formed `p + bi` before testing the offset, so a byte offset
outside the string produced an out-of-bounds pointer, and the single-byte
and binary fast path returned that offset instead of -1. Move the bounds
test to the top, where it covers the fast path and the pointer alike.

The non-UTF-8 identity function gets the same test, so the contract holds
on every build: -1 when the offset lies outside the string, and on UTF-8
builds also when it lands inside a multi-byte character.

Every caller clamps the offset it passes, so no behavior changes here.
The check belongs in the function now that it is internal API rather than
a static confined to this file.
@takumin
takumin requested a review from matz as a code owner August 12, 2026 04:08
@github-actions github-actions Bot added the core label Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c65bb7e-e446-4189-9e83-a69668f5ebd1

📥 Commits

Reviewing files that changed from the base of the PR and between 9eeea65 and f3e6127.

📒 Files selected for processing (2)
  • include/mruby/internal.h
  • src/string.c

📝 Walkthrough

Walkthrough

mrb_str_byte_to_char now rejects negative and oversized byte offsets in UTF-8 and non-UTF-8 builds. Its documentation describes bounds behavior and identity conversion for non-UTF-8 strings.

Changes

Byte-to-character conversion bounds

Layer / File(s) Summary
Validate conversion offsets
include/mruby/internal.h, src/string.c
mrb_str_byte_to_char rejects negative and out-of-range offsets. The UTF-8 implementation removes a redundant pointer check. The documentation describes UTF-8 and non-UTF-8 behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • mruby/mruby#7097: Introduces and modifies the same string byte-to-character conversion API.
  • mruby/mruby#7081: Modifies related string index and length handling in src/string.c.

Suggested reviewers: matz

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding a bounds check to mrb_str_byte_to_char.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@matz
matz merged commit e24e810 into mruby:master Aug 12, 2026
20 of 21 checks passed
@takumin
takumin deleted the string-byte-to-char-bounds branch August 12, 2026 04:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants