Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safely retrieve self from proc in mrb_yield() #5951

Merged
merged 1 commit into from Mar 17, 2023
Merged

Conversation

dearblue
Copy link
Contributor

@dearblue dearblue commented Mar 14, 2023

Safely retrieve self from proc in mrb_yield()

Passing a proc generated by the following method to mrb_yield() or mrb_yield_argv() no longer causes SIGSEGV:

  • C functions made into proc objects with mrb_proc_new_cfunc().
  • A proc object which is the top level of a program generated by mrb_load_string_cxt() etc. with mrbc_context::no_exec enabled.

See also: #5932

@dearblue dearblue requested a review from matz as a code owner March 14, 2023 14:16
src/proc.c Outdated
* Probably created by mrb_load_irep(), mrb_load_string() or etc.,
* or occurred a out of memory in mrb_env_unshare().
*/
mrb_raise(mrb, E_ARGUMENT_ERROR, "self is lost");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about returning mrb_top_self instead of raising an exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not very positive.

I'm concerned that if mrb_top_self is used, there will be a mismatch with the self that the user expects, and this will cause confusion.
Is it really appropriate to return mrb_top_self?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. As far as I see in the example in #5932, the issue happens with top-level proc. So the natural assumption for the receiver should be the toplevel self for most of the cases

On the other hand, if it raises exception, the user would be confused by not knowing how to handle this kind of error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand. Let's change it that way.

However, I would like to make an exception if mrb_env_unshare() encounters out of memory.
I expect this can be detected by MRB_ENV_LEN(env) == 0.

Relatedly, I would also allow the target class to be retrieved by mrb_proc_get_self().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change completed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@dearblue dearblue changed the title Safely retrieve self from proc Safely retrieve self from proc in mrb_yield() Mar 16, 2023
src/proc.c Outdated

if (!e || e->tt != MRB_TT_ENV) {
mrb_value self = mrb_top_self(mrb);
*target_class_p = mrb_class(mrb, self);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, top-level target class should be mrb->object_class I think.

Passing a proc generated by the following method to `mrb_yield()` or `mrb_yield_argv()` no longer causes `SIGSEGV`:

- C functions made into proc objects with `mrb_proc_new_cfunc()`.
- A proc object which is the top level of a program generated by `mrb_load_string_cxt()` etc. with `mrbc_context::no_exec` enabled.

See also: mruby#5932
@dearblue
Copy link
Contributor Author

Right, I agree.
Changed.

@matz matz merged commit db11e07 into mruby:master Mar 17, 2023
@dearblue dearblue deleted the mrb_yield branch April 9, 2023 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants