[Rd] segfault with POSIXlt zone=NULL zone=""
Martin Maechler
maechler at stat.math.ethz.ch
Tue Dec 6 18:49:05 CET 2016
>>>>> Joshua Ulrich <josh.m.ulrich at gmail.com>
>>>>> on Tue, 6 Dec 2016 09:51:16 -0600 writes:
> On Tue, Dec 6, 2016 at 6:37 AM, <frederik at ofb.net> wrote:
>> Hi all,
>>
>> I ran into a segfault while playing with dates.
>>
>> $ R --no-init-file
>> ...
>> > library(lubridate); d=as.POSIXlt(floor_date(Sys.time(),"year")); d$zone=NULL; d$zone=""; d
>>
> If you're asking about a bug in R, you should provide a *minimal*
> reproducible example (i.e. one without any package dependencies).
> This has nothing to do with lubridate, so you can reproduce the
> behavior with:
> d <- as.POSIXlt(Sys.time())
> d$zone <- NULL
> d$zone <- ""
> d
[..........]
>> Hope I'm not doing something illegal...
>>
> You are. You're changing the internal structure of a POSIXlt object
> by re-ordering the list elements. You should not expect a malformed
> POSIXlt object to behave as if it's correctly formed. You can see
> it's malformed by comparing it's unclass()'d output.
> d <- as.POSIXlt(Sys.time())
> unclass(d) # valid POSIXlt object
> d$zone <- NULL
> d$zone <- ""
> unclass(d) # your malformed POSIXlt object
Indeed, really illegal, i.e. "against the law" ... ;-)
Thank you, Joshua!
Still, if R segfaults without the user explicitly
calling .Call(), .Internal() or similar -- as here --
we usually acknowledge there *is* a bug in R .. even if it is
only triggered by a users "illegal" messing around.
an MRE for the above, where I really only re-order the "internal" list:
d <- as.POSIXlt("2016-12-06"); dz <- d$zone; d$zone <- NULL; d$zone <- dz; f <- format(d)
> *** caught segfault ***
> address 0x80000020, cause 'memory not mapped'
> Traceback:
> 1: format.POSIXlt(d)
> 2: format(d)
The current code is "optimized for speed" (not perfectly), and
a patch should hopefully address the C code.
Note that a smaller MRE -- which does *not* re-order, but just
invalidate the time zone is
d <- as.POSIXlt("2016-12-06"); d$zone <- 1; f <- format(d)
------
I have now committed a "minimal" patch (to the C code) which for
the above two cases gives a sensible error rather than a
seg.fault :
> d <- as.POSIXlt("2016-12-06"); d$zone <- 1 ; f <- format(d)
Error in format.POSIXlt(d) :
invalid 'zone' component in "POSIXlt" structure
> d <- as.POSIXlt("2016-12-06"); dz <- d$zone; d$zone <- NULL; d$zone <- dz; f <- format(d)
Error in format.POSIXlt(d) :
invalid 'zone' component in "POSIXlt" structure
>
I guess that it should still be possible to produce a segfault
with invalid 'POSIXlt' structures though.
Martin
More information about the R-devel
mailing list