diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-03-02 14:13:06 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-03-02 14:13:06 +0900 |
| commit | ca0dcbb22662eda2f6843cca14256c57cbd585e4 (patch) | |
| tree | 7cecd4d9b3d942f0e38c65cfea7183f131a7406b /mrbgems/mruby-time | |
| parent | e5649eba709a1479e32f332acdb0d847ef10c582 (diff) | |
| download | mruby-ca0dcbb22662eda2f6843cca14256c57cbd585e4.tar.gz mruby-ca0dcbb22662eda2f6843cca14256c57cbd585e4.zip | |
Free `struct mrb_time` before error; fix #4308
To avoid memory leak from `time_update_datetime`.
Diffstat (limited to 'mrbgems/mruby-time')
| -rw-r--r-- | mrbgems/mruby-time/src/time.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index d70fb442c..7f6c3004d 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -198,9 +198,10 @@ struct mrb_time { static const struct mrb_data_type mrb_time_type = { "Time", mrb_free }; /** Updates the datetime of a mrb_time based on it's timezone and -seconds setting. Returns self on success, NULL of failure. */ + seconds setting. Returns self on success, NULL of failure. + if `dealloc` is set `true`, it frees `self` on error. */ static struct mrb_time* -time_update_datetime(mrb_state *mrb, struct mrb_time *self) +time_update_datetime(mrb_state *mrb, struct mrb_time *self, int dealloc) { struct tm *aid; @@ -211,7 +212,10 @@ time_update_datetime(mrb_state *mrb, struct mrb_time *self) aid = localtime_r(&self->sec, &self->datetime); } if (!aid) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec)); + mrb_float sec = (mrb_float)self->sec; + + mrb_free(mrb, self); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); /* not reached */ return NULL; } @@ -273,7 +277,7 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) tm->sec += sec2; } tm->timezone = timezone; - time_update_datetime(mrb, tm); + time_update_datetime(mrb, tm, TRUE); return tm; } @@ -325,7 +329,7 @@ current_mrb_time(mrb_state *mrb) } #endif tm->timezone = MRB_TIMEZONE_LOCAL; - time_update_datetime(mrb, tm); + time_update_datetime(mrb, tm, TRUE); return tm; } @@ -616,7 +620,7 @@ mrb_time_getutc(mrb_state *mrb, mrb_value self) tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_UTC; - time_update_datetime(mrb, tm2); + time_update_datetime(mrb, tm2, TRUE); return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } @@ -631,7 +635,7 @@ mrb_time_getlocal(mrb_state *mrb, mrb_value self) tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); *tm2 = *tm; tm2->timezone = MRB_TIMEZONE_LOCAL; - time_update_datetime(mrb, tm2); + time_update_datetime(mrb, tm2, TRUE); return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); } @@ -709,7 +713,7 @@ mrb_time_localtime(mrb_state *mrb, mrb_value self) tm = time_get_ptr(mrb, self); tm->timezone = MRB_TIMEZONE_LOCAL; - time_update_datetime(mrb, tm); + time_update_datetime(mrb, tm, FALSE); return self; } @@ -806,7 +810,7 @@ mrb_time_utc(mrb_state *mrb, mrb_value self) tm = time_get_ptr(mrb, self); tm->timezone = MRB_TIMEZONE_UTC; - time_update_datetime(mrb, tm); + time_update_datetime(mrb, tm, FALSE); return self; } |
