Project

General

Profile

Actions

Bug #22103

closed

Constant-folded /o regexp crashes with dupstring of a Regexp

Bug #22103: Constant-folded /o regexp crashes with dupstring of a Regexp

Added by shugo (Shugo Maeda) 4 days ago. Updated 2 days ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:125692]

Description

A /o (once) regexp whose interpolation folds to a constant crashes at runtime:

def m; /#{"a"}/o; end
m   #=> [BUG] heap_idx_for_size: allocation size too large

A plain /#{"a"}/ (no /o) is fine.

Updated by shugo (Shugo Maeda) 3 days ago Actions #2

  • Status changed from Open to Closed

Applied in changeset git|0f211465887a601a9a1eb1b8d4f5174c852b4939.


compile.c: fix dupstring-of-Regexp from folded /o regexp

The peephole optimizer folds "dupstring str; toregexp" (and the
dupchilledstring / putobject-string variants) into a single
literal-push by compiling the Regexp at compile time and replacing the
operand with it. It replaced the operand but kept the original opcode,
so a dupstring/dupchilledstring instruction was left holding a Regexp.
At run time dupstring resurrects its operand as a String
(rb_ec_str_resurrect), reading the Regexp as if it were a string and
crashing ("heap_idx_for_size: allocation size too large").

This is reachable from a /o regexp whose interpolation folds to a
constant, e.g. def m; /#{"a"}/o; end: the once body is compiled via
the dynamic-regexp path (dupstring + toregexp) and then folded, unlike
a plain /#{"a"}/ which is pushed directly with putobject.

Set the opcode to putobject when folding, matching what a static regexp
literal emits.

Fixes [Bug #22103].

Co-Authored-By: Claude Opus 4.8

Updated by luke-gru (Luke Gruber) 2 days ago Actions #3

  • Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN to 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: REQUIRED
Actions

Also available in: PDF Atom