* time.c (GetTimeval): check if already initialized instance.
* time.c (GetNewTimeval): check if newly created instance.
* time.c (time_init_0, time_init_1, time_init_copy, time_mload): must
  be newly created instance.  [ruby-core:53436] [Bug #8099]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39766 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-03-15 14:06:21 +00:00
Родитель 55549b85f1
Коммит 84085167f8
3 изменённых файлов: 53 добавлений и 7 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Fri Mar 15 23:06:18 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* time.c (GetTimeval): check if already initialized instance.
* time.c (GetNewTimeval): check if newly created instance.
* time.c (time_init_0, time_init_1, time_init_copy, time_mload): must
be newly created instance. [ruby-core:53436] [Bug #8099]
Fri Mar 15 14:51:33 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* file.c (rb_sys_fail_path_with_func): share same function, and path

Просмотреть файл

@ -408,6 +408,15 @@ class TestTime < Test::Unit::TestCase
assert_kind_of(Integer, t2000.hash)
end
def test_reinitialize
bug8099 = '[ruby-core:53436] [Bug #8099]'
t2000 = get_t2000
assert_raise(TypeError, bug8099) {
t2000.send(:initialize, 2013, 03, 14)
}
assert_equal(get_t2000, t2000, bug8099)
end
def test_init_copy
t2000 = get_t2000
assert_equal(t2000, t2000.dup)

42
time.c
Просмотреть файл

@ -1823,10 +1823,11 @@ struct time_object {
int tm_got;
};
#define GetTimeval(obj, tobj) \
TypedData_Get_Struct((obj), struct time_object, &time_data_type, (tobj))
#define GetTimeval(obj, tobj) ((tobj) = get_timeval(obj))
#define GetNewTimeval(obj, tobj) ((tobj) = get_new_timeval(obj))
#define IsTimeval(obj) rb_typeddata_is_kind_of((obj), &time_data_type)
#define TIME_INIT_P(tobj) ((tobj)->gmt != -1)
#define TIME_UTC_P(tobj) ((tobj)->gmt == 1)
#define TIME_SET_UTC(tobj) ((tobj)->gmt = 1)
@ -1889,12 +1890,35 @@ time_s_alloc(VALUE klass)
struct time_object *tobj;
obj = TypedData_Make_Struct(klass, struct time_object, &time_data_type, tobj);
tobj->gmt = -1;
tobj->tm_got=0;
tobj->timew = WINT2FIXWV(0);
return obj;
}
static struct time_object *
get_timeval(VALUE obj)
{
struct time_object *tobj;
TypedData_Get_Struct(obj, struct time_object, &time_data_type, tobj);
if (!TIME_INIT_P(tobj)) {
rb_raise(rb_eTypeError, "uninitialized %"PRIsVALUE, CLASS_OF(obj));
}
return tobj;
}
static struct time_object *
get_new_timeval(VALUE obj)
{
struct time_object *tobj;
TypedData_Get_Struct(obj, struct time_object, &time_data_type, tobj);
if (TIME_INIT_P(tobj)) {
rb_raise(rb_eTypeError, "already initialized %"PRIsVALUE, CLASS_OF(obj));
}
return tobj;
}
static void
time_modify(VALUE time)
{
@ -1960,7 +1984,8 @@ time_init_0(VALUE time)
struct timespec ts;
time_modify(time);
GetTimeval(time, tobj);
GetNewTimeval(time, tobj);
tobj->gmt = 0;
tobj->tm_got=0;
tobj->timew = WINT2FIXWV(0);
#ifdef HAVE_CLOCK_GETTIME
@ -2203,7 +2228,8 @@ time_init_1(int argc, VALUE *argv, VALUE time)
validate_vtm(&vtm);
time_modify(time);
GetTimeval(time, tobj);
GetNewTimeval(time, tobj);
tobj->gmt = 0;
tobj->tm_got=0;
tobj->timew = WINT2FIXWV(0);
@ -2320,7 +2346,8 @@ time_new_timew(VALUE klass, wideval_t timew)
VALUE time = time_s_alloc(klass);
struct time_object *tobj;
GetTimeval(time, tobj);
tobj = DATA_PTR(time); /* skip type check */
tobj->gmt = 0;
tobj->timew = timew;
return time;
@ -3447,7 +3474,7 @@ time_init_copy(VALUE copy, VALUE time)
if (!OBJ_INIT_COPY(copy, time)) return copy;
GetTimeval(time, tobj);
GetTimeval(copy, tcopy);
GetNewTimeval(copy, tcopy);
MEMCPY(tcopy, tobj, struct time_object, 1);
return copy;
@ -4832,7 +4859,8 @@ end_submicro: ;
timew = timegmw(&vtm);
}
GetTimeval(time, tobj);
GetNewTimeval(time, tobj);
tobj->gmt = 0;
tobj->tm_got = 0;
tobj->timew = timew;
if (gmt) {