Skip to content

Commit

Permalink
Memcpy, memmove and memset should be only called on valid pointers ev…
Browse files Browse the repository at this point in the history
…en when

the size is zero to avoid undefined behavior.


git-svn-id: https://svn.r-project.org/R/trunk@87180 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
kalibera committed Sep 20, 2024
1 parent d58f6f8 commit a8a07f2
Show file tree
Hide file tree
Showing 33 changed files with 174 additions and 102 deletions.
3 changes: 2 additions & 1 deletion src/extra/graphapp/bitmaps.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ bitmap imagetobitmap(image img)
data[i+2] = getred(colour);
}
}
else memcpy(data, pixel32, 4*height*width);
else if (height && width)
memcpy(data, pixel32, 4*height*width);

/* Create the bitmap from the DIB data.
Could also use CreateDIBsection */
Expand Down
4 changes: 2 additions & 2 deletions src/extra/xdr/xdr_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ xdrmem_getbytes(

if ((xdrs->x_handy -= len) < 0)
return (FALSE);
memcpy(addr, xdrs->x_private, len);
if (len) memcpy(addr, xdrs->x_private, len);
xdrs->x_private += len;
return (TRUE);
}
Expand All @@ -182,7 +182,7 @@ xdrmem_putbytes(

if ((xdrs->x_handy -= len) < 0)
return (FALSE);
memcpy(xdrs->x_private, addr, len);
if (len) memcpy(xdrs->x_private, addr, len);
xdrs->x_private += len;
return (TRUE);
}
Expand Down
3 changes: 2 additions & 1 deletion src/gnuwin32/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -2000,7 +2000,8 @@ int consolereads(control c, const char *prompt, char *buf, int len,
segment is empty (should not happen) or
internal segment of line of same length as buffer */

memcpy(buf, segment, slen);
if (slen)
memcpy(buf, segment, slen);
free(segment);
buf[slen] = '\0';
return res;
Expand Down
12 changes: 6 additions & 6 deletions src/gnuwin32/getline/getline.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,10 @@ gl_realloc(void *ptr, int olditems, int newitems, size_t itemsize)
void *res;
if (!(res = realloc(ptr, newitems * itemsize)))
gl_error("\n*** Error: getline(): not enough memory.\n");
memset(((char *)res) + olditems * itemsize,
0,
(newitems - olditems) * itemsize);
if (newitems > olditems)
memset(((char *)res) + olditems * itemsize,
0,
(newitems - olditems) * itemsize);
return res;
}

Expand Down Expand Up @@ -1556,11 +1557,10 @@ hist_save(const char *p)
{
char *s = 0;
int len = strlen(p);
char *nl = strchr(p, '\n');

if (nl) {
if (len && p[len - 1] == '\n') {
if ((s = (char *) malloc(len)) != 0) {
memcpy(s, p, len-1);
memcpy(s, p, len-1);
s[len-1] = 0;
}
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/gnuwin32/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ CharReadConsole(const char *prompt, unsigned char *buf, int len,
int tocopy = remaining;
if (tocopy > len - 1) tocopy = len - 1;

memcpy(buf, line + offset, tocopy);
if (tocopy)
memcpy(buf, line + offset, tocopy);
buf[tocopy] = '\0';
remaining -= tocopy;
offset += tocopy;
Expand Down
6 changes: 4 additions & 2 deletions src/include/R_ext/RS.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ extern "C" {
extern void *R_chk_calloc(R_SIZE_T, R_SIZE_T);
extern void *R_chk_realloc(void *, R_SIZE_T);
extern void R_chk_free(void *);
extern void *R_chk_memcpy(void *, const void *, R_SIZE_T);
extern void *R_chk_memset(void *, int, R_SIZE_T);

#ifndef STRICT_R_HEADERS
/* S-PLUS 3.x but not 5.x NULLed the pointer in Free.
Expand All @@ -64,10 +66,10 @@ extern void R_chk_free(void *);
#define R_Free(p) (R_chk_free( (void *)(p) ), (p) = NULL)

/* Nowadays API: undocumented until 4.1.2: widely used. */
#define Memcpy(p,q,n) memcpy( p, q, (R_SIZE_T)(n) * sizeof(*p) )
#define Memcpy(p,q,n) R_chk_memcpy( p, q, (R_SIZE_T)(n) * sizeof(*p) )

/* Nowadays API: added for 3.0.0 but undocumented until 4.1.2. */
#define Memzero(p,n) memset(p, 0, (R_SIZE_T)(n) * sizeof(*p))
#define Memzero(p,n) R_chk_memset(p, 0, (R_SIZE_T)(n) * sizeof(*p))

/* API: Added in R 2.6.0 */
#define CallocCharBuf(n) (char *) R_chk_calloc(((R_SIZE_T)(n))+1, sizeof(char))
Expand Down
3 changes: 2 additions & 1 deletion src/library/graphics/src/stem.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ C_bincount(double *x, R_xlen_t n, double *breaks, R_xlen_t nb, int *count,
R_xlen_t i, lo, hi, nb1 = nb - 1, new;

// for(i = 0; i < nb1; i++) count[i] = 0;
memset(count, 0, nb1 * sizeof(int));
if (nb1)
memset(count, 0, nb1 * sizeof(int));

for(i = 0 ; i < n ; i++)
if(R_FINITE(x[i])) { // left in as a precaution
Expand Down
4 changes: 2 additions & 2 deletions src/library/stats/src/HoltWinters.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* R : A Computer Language for Statistical Data Analysis
*
* Copyright (C) 2003-7 The R Core Team
* Copyright (C) 2003-24 The R Core Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -54,7 +54,7 @@ void HoltWinters (double *x,
/* copy start values to the beginning of the vectors */
level[0] = *a;
if (*dotrend == 1) trend[0] = *b;
if (*doseasonal == 1) memcpy(season, s, *period * sizeof(double));
if (*doseasonal == 1 && *period) memcpy(season, s, *period * sizeof(double));

for (i = *start_time - 1; i < *xl; i++) {
/* indices for period i */
Expand Down
11 changes: 7 additions & 4 deletions src/library/stats/src/ansari.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1999-2016 The R Core Team
* Copyright (C) 1999-2024 The R Core Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,10 +35,12 @@ w_init(int m, int n)
double ***w;

w = (double ***) R_alloc(m + 1, sizeof(double **));
memset(w, '\0', (m+1) * sizeof(double**));
if (m+1)
memset(w, '\0', (m+1) * sizeof(double**));
for (i = 0; i <= m; i++) {
w[i] = (double**) R_alloc(n + 1, sizeof(double *));
memset(w[i], '\0', (n+1) * sizeof(double*));
if (n+1)
memset(w[i], '\0', (n+1) * sizeof(double*));
}
return(w);
}
Expand All @@ -57,7 +59,8 @@ cansari(int k, int m, int n, double ***w)

if (w[m][n] == 0) {
w[m][n] = (double *) R_alloc(u + 1, sizeof(double));
memset(w[m][n], '\0', (u + 1) * sizeof(double));
if (u+1)
memset(w[m][n], '\0', (u + 1) * sizeof(double));
for (i = 0; i <= u; i++)
w[m][n][i] = -1;
}
Expand Down
8 changes: 5 additions & 3 deletions src/library/stats/src/kendall.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1999-2016 The R Core Team.
* Copyright (C) 1999-2024 The R Core Team.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -40,7 +40,8 @@ ckendall(int k, int n, double **w)
if ((k < 0) || (k > u)) return(0);
if (w[n] == 0) {
w[n] = (double *) R_alloc(u + 1, sizeof(double));
memset(w[n], '\0', sizeof(double) * (u+1));
if (u+1)
memset(w[n], '\0', sizeof(double) * (u+1));
for (i = 0; i <= u; i++) w[n][i] = -1;
}
if (w[n][k] < 0) {
Expand Down Expand Up @@ -82,7 +83,8 @@ pkendall(int len, double *Q, double *P, int n)
double **w;

w = (double **) R_alloc(n + 1, sizeof(double *));
memset(w, '\0', sizeof(double*) * (n+1));
if (n+1)
memset(w, '\0', sizeof(double*) * (n+1));

for (i = 0; i < len; i++) {
q = floor(Q[i] + 1e-7);
Expand Down
5 changes: 3 additions & 2 deletions src/library/stats/src/model.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1997--2023 The R Core Team
* Copyright (C) 1997--2024 The R Core Team
* Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -1274,7 +1274,8 @@ static void ExtractVars(SEXP formula)
static SEXP AllocTerm(void) // (<global> nwords)
{
SEXP term = allocVector(INTSXP, nwords); // caller must PROTECT
memset(INTEGER(term), 0, nwords * sizeof(int));
if (nwords)
memset(INTEGER(term), 0, nwords * sizeof(int));
return term;
}

Expand Down
5 changes: 3 additions & 2 deletions src/library/stats/src/port.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2005-2022 The R Core Team.
* Copyright (C) 2005-2024 The R Core Team.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -236,7 +236,8 @@ double F77_NAME(dv2nrm)(int *n, const double x[])
void F77_NAME(dv7cpy)(int *n, double dest[], const double src[])
{
/* Was memcpy, but overlaps seen */
memmove(dest, src, *n * sizeof(double));
if (*n)
memmove(dest, src, *n * sizeof(double));
}

/* dv7ipr... applies forward permutation to vector. */
Expand Down
5 changes: 3 additions & 2 deletions src/library/stats/src/rWishart.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2012-2022 The R Core Team
* Copyright (C) 2012-2024 The R Core Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -92,7 +92,8 @@ rWishart(SEXP ns, SEXP nuP, SEXP scal)
scCp = R_Calloc(psqr, double);

Memcpy(scCp, REAL(scal), psqr);
memset(tmp, 0, psqr * sizeof(double));
if (psqr)
memset(tmp, 0, psqr * sizeof(double));
F77_CALL(dpotrf)("U", &(dims[0]), scCp, &(dims[0]), &info FCONE); // LAPACK
if (info)
error(_("'scal' matrix is not positive-definite"));
Expand Down
3 changes: 2 additions & 1 deletion src/library/tools/src/gramRd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3208,7 +3208,8 @@ static SEXP xxusermacro(SEXP macro, SEXP args, YYLTYPE *lloc)
SEXP stri = CAR(si);
if (!isComment(stri)) {
int nc = LENGTH(STRING_ELT(stri, 0));
memcpy(str + offset, CHAR(STRING_ELT(stri, 0)), nc);
if (nc)
memcpy(str + offset, CHAR(STRING_ELT(stri, 0)), nc);
offset += nc;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/library/tools/src/gramRd.y
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,8 @@ static SEXP xxusermacro(SEXP macro, SEXP args, YYLTYPE *lloc)
SEXP stri = CAR(si);
if (!isComment(stri)) {
int nc = LENGTH(STRING_ELT(stri, 0));
memcpy(str + offset, CHAR(STRING_ELT(stri, 0)), nc);
if (nc)
memcpy(str + offset, CHAR(STRING_ELT(stri, 0)), nc);
offset += nc;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/main/altclasses.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2016--2023 The R Core Team
* Copyright (C) 2016--2024 The R Core Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -690,7 +690,8 @@ static R_INLINE SEXP ExpandDeferredStringElt(SEXP x, R_xlen_t i)
if (val == R_NilValue) {
R_xlen_t n = XLENGTH(x);
val = allocVector(STRSXP, n);
memset(STDVEC_DATAPTR(val), 0, n * sizeof(SEXP));
if (n)
memset(STDVEC_DATAPTR(val), 0, n * sizeof(SEXP));
SET_DEFERRED_STRING_EXPANDED(x, val);
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/apply.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2000-2023 The R Core Team
* Copyright (C) 2000-2024 The R Core Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -206,7 +206,7 @@ attribute_hidden SEXP do_vapply(SEXP call, SEXP op, SEXP args, SEXP rho)
case STRSXP: SET_STRING_ELT(ans, i, STRING_ELT(val, 0)); break;
case VECSXP: SET_VECTOR_ELT(ans, i, VECTOR_ELT(val, 0)); break;
}
} else { // commonLen > 1 (typically, or == 0) :
} else if (commonLen) { // commonLen > 1
switch (commonType) {
case REALSXP:
memcpy(REAL(ans) + common_len_offset,
Expand Down
Loading

0 comments on commit a8a07f2

Please sign in to comment.