Skip to content

Time#utc and #localtime can mutate a frozen object #4655

@iconara

Description

@iconara

Environment

This is one of the relevant environments, but the issue can be replicated in all environments I've tested:

$ ruby -v
jruby 9.1.8.0 (2.3.1) 2017-03-06 90fc7ab Java HotSpot(TM) 64-Bit Server VM 25.112-b16 on 1.8.0_112-b16 +jit [darwin-x86_64]
$ uname -a
Darwin quattro.local 16.6.0 Darwin Kernel Version 16.6.0: Fri Apr 14 16:21:16 PDT 2017; root:xnu-3789.60.24~6/RELEASE_X86_64 x86_64

Expected Behavior

When I freeze a Time instance I expect to not be able to run #utc since that method changes the instance:

irb> Time.new.freeze.utc
RuntimeError: can't modify frozen Time
	from (irb):1:in `utc'
	from (irb):1

The same goes for #localtime:

irb>  Time.new.utc.freeze.localtime
RuntimeError: can't modify frozen Time
	from (irb):1:in `localtime'
	from (irb):1

Actual Behavior

In all versions of JRuby I have tested (1.7.19, 1.7.23, 1.7.26, 9.0.5.0, 9.1.8.0) I can modify frozen Time instances:

irb> t = Time.now
=> 2017-06-08 10:12:04 +0200
irb> t.freeze
=> 2017-06-08 10:12:04 +0200
irb> t.frozen?
=> true
irb> t.utc
=> 2017-06-08 08:12:04 UTC
irb> t
=> 2017-06-08 08:12:04 UTC
irb> t.localtime
=> 2017-06-08 10:12:04 +0200
irb> t
=> 2017-06-08 10:12:04 +0200

It looks like problem lies in these two lines:

I've looked through the rest of RubyTime.java and it looks like these are the only place where dt or nsec are changed except for at initialization time.

Even though this is inconsistent behaviour with MRI it could potentially break a lot of code so I assume it's not something that could be rolled out in a patch release.

It looks like an easy fix, and I'd love to submit a PR, but I need is a pointer to where to add a test for it. Would adding a test/test_time_freeze.rb be the right thing to do?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions