In that case it seems like just erroring instead of returning invalid
pointers is a much friendlier option. Why give developers an unpinned
grenade to carry around?

On Wed, Apr 23, 2025 at 1:38 PM Tomas Kalibera <tomas.kalib...@gmail.com> wrote:
>
> On 4/23/25 19:03, Michael Chirico wrote:
> > h/t Tim Taylor for pointing out my blindspot :)
> >
> > We have Memcpy() in API already [1], which wraps a 0-aware R_chk_memcpy() 
> > [2].
> >
> > We don't quite have Memset() in API, though; instead we have Memzero()
> > [3] for R_chk_memset(s, 0, n) which is 0-aware memset() [4].
>
> I don't think that using wrappers for this is the right approach. Even
> loading an invalid pointer is undefined behavior. While it wouldn't
> matter on typical hardware where R is used today, it could cause a crash
> on some hardware, and it may well be that various checkers will start
> warning about such things. Also, holding (intentionally) invalid
> pointers makes debugging harder.
>
> At least in new code, I would avoid holding invalid pointers. Certainly
> I don't think we should be adding wrappers to R for C functions to make
> them work with invalid pointers.
>
> Best
> Tomas
>
> >
> > [1] 
> > https://github.com/r-devel/r-svn/blob/9e597ca8132e8b6298b0bedb39fa8deba5c819df/src/include/R_ext/RS.h#L59-L60
> > [2] 
> > https://github.com/r-devel/r-svn/blob/9e597ca8132e8b6298b0bedb39fa8deba5c819df/src/main/memory.c#L3575-L3580
> > [3] 
> > https://github.com/r-devel/r-svn/blob/9e597ca8132e8b6298b0bedb39fa8deba5c819df/src/include/R_ext/RS.h#L62-L63
> > [4] 
> > https://github.com/r-devel/r-svn/blob/9e597ca8132e8b6298b0bedb39fa8deba5c819df/src/main/memory.c#L3582-L3587
> >
> > Mike C
> >
> > On Wed, Apr 23, 2025 at 8:57 AM Michael Chirico
> > <michaelchiri...@gmail.com> wrote:
> >>  From R 4.5.0 [1], all builds of R discourage use of INTEGER() [and
> >> friends REAL(), ... and *_RO() equivalents] on length-0 SEXP [2].
> >> Before R 4.5.0, this was the behavior under --enable-strict-barrier.
> >>
> >> That means the following can segfault under strict builds (e.g.
> >> -fsanitize=alignment and -O0):
> >>
> >> SEXP x = PROTECT(Rf_allocVector(INTSXP, 0));
> >> SEXP y = PROTECT(Rf_allocVector(INTSXP, 0));
> >> const int *x = INTEGER_RO(x); // invalid!
> >> int *y = INTEGER(y);
> >> memcpy(y, x, 0); // alluring, but undefined behavior!
> >>
> >> There are a number of CRAN packages that fall victim to this, see e.g.
> >> this PR and others linked to it [3]. I'm sure there are dozens if not
> >> hundreds of other equivalent bugs waiting to be discovered that just
> >> aren't covered by existing tests.
> >>
> >> {rlang} took the approach to define r_memcpy() and r_memset() which
> >> wrap memcpy() and memset(), resp., with an added length-0 check [4]; I
> >> think R itself should offer these (probably more consistently styled
> >> as R_Memcpy() and R_Memset()).
> >>
> >> (NB there's a possibility I'm still not fully grasping what's going on 
> >> here :) )
> >>
> >> Mike C
> >>
> >> [1] related: https://stat.ethz.ch/pipermail/r-devel/2024-June/083456.html
> >> [2] 
> >> https://github.com/r-devel/r-svn/blob/2b29e52e1c4e3d26b649cb7ac320b8a3dd13de30/src/main/memory.c#L4146
> >> [3] https://github.com/r-lib/vctrs/pull/1968
> >> [4] https://github.com/r-lib/rlang/pull/1797
> > ______________________________________________
> > R-devel@r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to