@@ -380,6 +380,13 @@ mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fm
|
380 | 380 | argc++; |
381 | 381 | argv--; |
382 | 382 | mrb_ensure_string_type(mrb, fmt); |
| 383 | +/* Duplicate the format string so that to_s/inspect callbacks invoked |
| 384 | + during the loop cannot invalidate p/end by mutating the original |
| 385 | + via String#replace or similar. mrb_str_dup shares the underlying |
| 386 | + buffer, so this is O(1); String#replace on the original goes |
| 387 | + through str_replace which decrements the shared refcount, leaving |
| 388 | + our copy's buffer intact. */ |
| 389 | +fmt = mrb_str_dup(mrb, fmt); |
383 | 390 | p = RSTRING_PTR(fmt); |
384 | 391 | end = p + RSTRING_LEN(fmt); |
385 | 392 | blen = 0; |
|