-
Notifications
You must be signed in to change notification settings - Fork 192
[Bug] Fix singleton class lookup bug when singleton class is replaced on the instance #3088
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
[Bug] Fix singleton class lookup bug when singleton class is replaced on the instance #3088
Conversation
0927461
to
ec0f4f1
Compare
ec0f4f1
to
ec5aa00
Compare
ec5aa00
to
4fd4410
Compare
Thank you for your pull request and welcome to our community! To contribute, please sign the Oracle Contributor Agreement (OCA). To sign the OCA, please create an Oracle account and sign the OCA in Oracle's Contributor Agreement Application. When signing the OCA, please provide your GitHub username. After signing the OCA and getting an OCA approval from Oracle, this PR will be automatically updated. If you are an Oracle employee, please make sure that you are a member of the main Oracle GitHub organization, and your membership in this organization is public. |
4fd4410
to
1af8708
Compare
src/main/java/org/truffleruby/language/objects/MetaClassNode.java
Outdated
Show resolved
Hide resolved
52157b9
to
628e973
Compare
…e instance. Co-authored-by: Kevin Menard <[email protected]> Co-authored-by: Peter Arato <[email protected]> Co-authored-by: Benoit Daloze <[email protected]>
628e973
to
400a93a
Compare
IO#reopen
is one of those few examples (maybe the only one) where the caller object's singleton class is replaced:https://github.com/oracle/truffleruby/blob/master/src/main/ruby/truffleruby/core/io.rb#L1901
This means, methods defined only on an IO object's singleton class won't be available after calling
#reopen
on it.However, currently in TruffleRuby fetching the singleton class for an object is cached against the object - which makes an assumption that the same object must have the same singleton class during its lifetime. As the beginning states, this is not the case for IO objects currently.
An example where this occurs on production: ActiveSupport's test runner contains an IO capture mechanism: https://github.com/rails/rails/blob/0e99d0893b0e98c626a3c7d8972eea22d29c9d25/activesupport/lib/active_support/testing/stream.rb#L23-L38 This effectively erases
STDOUT
's singleton class. Any extension onSTDOUT
's singleton class, eg with this public gem could cause a lookup of the old singleton class function.The actual break on production was a bit more nuanced:
IO#write
method with a new proxy method, both on the singleton class (to enhance the functionality ofSTDOUT.write
).ActiveSupport
's#capture
mechanism, which deleted the singleton classSTDOUT.write
was - due to the bug - directed to the old metaclass'.write
method, which failed to call the old alias.To sum up the bug's effect, after replacing a singleton class: