Bug #8099

Time can be mutated by send :initialize

Added by Charles Nutter about 1 year ago. Updated about 1 year ago.

[ruby-core:53436]
Status:Closed
Priority:Normal
Assignee:-
Category:-
Target version:-
ruby -v:2.0.0p0 Backport:

Description

It is possible to alter the value of a given Time object by re-sending :initialize. No other methods can cause the time to be mutated, and I believe no method should modify the value of an already-initialized Time object.

Some examples:

ext-jruby-local ~/projects/jruby $ ruby2.0.0 -e "t = Time.now; p t; sleep 2; t.send(:initialize); p t"
2013-03-15 01:21:34 -0500
2013-03-15 01:21:36 -0500

ext-jruby-local ~/projects/jruby $ ruby2.0.0 -e "t = Time.now; p t; t.send(:initialize, 2013, 03, 14); p t"
2013-03-15 01:22:24 -0500
2013-03-14 00:00:00 -0500

If time is critical in an application and you can't trust that the Time object is immutable, all sorts of nasty tricks are possible.

Freezing does prevent reinitialization, but it seems like Time (or its value, at least!) should be immutable by default.

All codebases based on MRI's Time implementation exhibit this behavior. All non-MRI implementations I tested did not allow reinitialization or did not modify the Time object's value.

Note: Time#localtime does modify the time zone of a target Time object, but that does not change the essential value of the object. I would like to see #localtime go away as well.

Associated revisions

Revision 39766
Added by Nobuyoshi Nakada about 1 year ago

time.c: check re-initialize

  • time.c (GetTimeval): check if already initialized instance.
  • time.c (GetNewTimeval): check if newly created instance.
  • time.c (timeinit0, timeinit1, timeinitcopy, time_mload): must be newly created instance. [Bug #8099]

History

#1 Updated by Nobuyoshi Nakada about 1 year ago

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

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


time.c: check re-initialize

  • time.c (GetTimeval): check if already initialized instance.
  • time.c (GetNewTimeval): check if newly created instance.
  • time.c (timeinit0, timeinit1, timeinitcopy, time_mload): must be newly created instance. [Bug #8099]

Also available in: Atom PDF