Backport #7557

Module#initialize_copy allows to change the superclass of a class

Added by Charlie Somerville over 1 year ago. Updated over 1 year ago.

[ruby-core:50869]
Status:Closed
Priority:High
Assignee:Usaku NAKAMURA

Description

=begin

You can abuse (({Module#initializecopy})) to change the superclass of a class, because of this line of code in (({rbmodinitcopy})):

RCLASSSUPER(clone) = RCLASSSUPER(orig);

(({Class#initialize_copy})) does perform some checks to stop you calling (({#initialize})) on an already initialized class, but this can be subverted by redefining it to call (({super})) from Ruby-land.

Here's an example:

class Class
def initialize_copy(*)
super
end

def superclass=(klass)
  initialize_copy(Class.new(klass))
end

end

Symbol.superclass = String

p :hello.class.ancestors
# => [Symbol, String, Comparable, Object, Kernel, BasicObject]


Related issues

Related to Backport93 - Backport #8434: rb_class_init_copy was removed in r38364, but it is still... Closed 05/22/2013

Associated revisions

Revision 38507
Added by Usaku NAKAMURA over 1 year ago

merge revision(s) 38364,38366: [Backport #7557]

* object.c (Init_Object): use rb_mod_init_copy for Class#initialize_copy

* class.c (rb_class_init_copy): rename to class_init_copy_check, performs type
  checks on arguments to prevent reinitialization of initialized class
   [Bug #7557]

* class.c (rb_mod_init_copy): use class_init_copy_check if receiver is T_CLASS

* test/ruby/test_class.rb (class TestClass): related test

History

#1 Updated by Charlie Somerville over 1 year ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r38364.
Charlie, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • object.c (InitObject): use rbmodinitcopy for Class#initialize_copy
    • class.c (rbclassinitcopy): rename to classinitcopycheck, performs type checks on arguments to prevent reinitialization of initialized class [Bug #7557]
    • class.c (rbmodinitcopy): use classinitcopycheck if receiver is T_CLASS
    • test/ruby/test_class.rb (class TestClass): related test

#2 Updated by Nobuyoshi Nakada over 1 year ago

  • Tracker changed from Bug to Backport
  • Project changed from ruby-trunk to Backport93
  • Category deleted (core)
  • Status changed from Closed to Assigned
  • Assignee changed from Charlie Somerville to Usaku NAKAMURA
  • Priority changed from Normal to High

#3 Updated by Usaku NAKAMURA over 1 year ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r38507.
Charlie, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


merge revision(s) 38364,38366: [Backport #7557]

* object.c (Init_Object): use rb_mod_init_copy for Class#initialize_copy

* class.c (rb_class_init_copy): rename to class_init_copy_check, performs type
  checks on arguments to prevent reinitialization of initialized class
   [Bug #7557]

* class.c (rb_mod_init_copy): use class_init_copy_check if receiver is T_CLASS

* test/ruby/test_class.rb (class TestClass): related test

Also available in: Atom PDF