patch against overflows in saveload.c
Jean Meloche
jean@stat.ubc.ca
Fri, 02 Apr 1999 21:58:54 +0000
This is a multi-part message in MIME format.
--------------3F9F11E6B00532CFDD5A424A
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
R fails to save long strings... (with xdr)
> str<-''; for(i in c(0:1000)) str<-paste(str,'a')
> q(save='yes')
Error: a write error occured
>
This was noticed a while ago and someone
suggested a large fixed sized buffer.
The attached patch allocates a buffer as needed
using malloc. I know R has ist own allocation
mechanism but I figured malloc was ok for
such short-lived buffers.
If not, please let me know how to do it properly.
--
Jean Meloche
--------------3F9F11E6B00532CFDD5A424A
Content-Type: text/plain; charset=us-ascii;
name="sl.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="sl.diff"
--- saveload.c Tue Feb 16 09:15:59 1999
+++ /usr/local/R-0.63.3/src/main/saveload.c Fri Apr 2 13:25:42 1999
@@ -1,7 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
- * Copyright (C) 1997--1999 Robert Gentleman, Ross Ihaka and 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
@@ -61,7 +60,7 @@
static int (*InInteger)(FILE*);
static double (*InReal)(FILE*);
static complex (*InComplex)(FILE*);
-static char* (*InString)(FILE*);
+static char* (*InString)(FILE*,int,char *);
static void (*InTerm)(FILE*);
@@ -195,7 +194,7 @@
fputc('\"', fp);
}
-static char *AsciiInString(FILE *fp)
+static char *AsciiInString(FILE *fp, int len, char *buf)
{
int c;
bufp = buf;
@@ -346,16 +345,17 @@
static void XdrOutString(FILE *fp, char *s)
{
- if (!xdr_string(&xdrs, &s, MAXELTSIZE - 1)) {
+ if (!xdr_string(&xdrs, &s, strlen(s))) {
xdr_destroy(&xdrs);
error("a write error occured\n");
}
}
-static char *XdrInString(FILE *fp)
+static char *XdrInString(FILE *fp, int len, char *buf)
{
- char *bufp = buf;
- if (!xdr_string(&xdrs, &bufp, MAXELTSIZE - 1)) {
+ char *bufp;
+ bufp=buf;
+ if (!xdr_string(&xdrs, &bufp, len)) {
xdr_destroy(&xdrs);
error("a read error occured\n");
}
@@ -439,7 +439,7 @@
error("a write error occured\n");
}
-static char *BinaryInString(FILE *fp)
+static char *BinaryInString(FILE *fp, int len, char *buf)
{
bufp = buf;
do {
@@ -705,6 +705,8 @@
OutSpace(fp);
OutInteger(fp, NodeToOffset(&R_NHeap[i]));
OutSpace(fp);
+ OutInteger(fp, strlen(CHAR(PRINTNAME(&R_NHeap[i]))));
+ OutSpace(fp);
OutString(fp, CHAR(PRINTNAME(&R_NHeap[i])));
OutNewline(fp);
k++;
@@ -737,7 +739,6 @@
for (i = 0; i < R_NSize; i++) {
if (MARK(&R_NHeap[i])) {
if (TYPEOF(&R_NHeap[i]) != SYMSXP) {
-
OutInteger(fp, n);
OutSpace(fp);
OutInteger(fp, TYPEOF(&R_NHeap[i]));
@@ -845,6 +846,7 @@
{
unsigned int j;
int len;
+ char *buf;
TYPEOF(s) = InInteger(fp);
@@ -887,12 +889,16 @@
case SPECIALSXP:
case BUILTINSXP:
len = InInteger(fp);
- PRIMOFFSET(s) = StrToInternal(InString(fp));
+ if((buf=malloc(len+1))==NULL) error("not enough memory to restore data\n");
+ PRIMOFFSET(s) = StrToInternal(InString(fp, len, buf));
+ free(buf);
break;
case CHARSXP:
LENGTH(s) = len = InInteger(fp);
ReallocString(s, len);
- strcpy(CHAR(s), InString(fp));
+ if((buf=malloc(len+1))==NULL) error("not enough memory to restore data\n");
+ strcpy(CHAR(s), InString(fp, len, buf));
+ free(buf);
break;
case REALSXP:
LENGTH(s) = len = InInteger(fp);
@@ -956,9 +962,14 @@
/* computing the forwarding addresses */
for (i = 0 ; i < NSymbol ; i++) {
+ char *buf;
+ int len;
j = InInteger(fp);
OldOffset[j] = InInteger(fp);
- NewAddress[j] = install(InString(fp));
+ len = InInteger(fp);
+ if((buf=malloc(len+1))==NULL) error("not enough memory to restore data\n");
+ NewAddress[j] = install(InString(fp,len,buf));
+ free(buf);
}
/* symbols are all installed */
@@ -1074,7 +1085,7 @@
TAG(t) = install(CHAR(STRING(CAR(args))[j]));
CAR(t) = findVar(TAG(t), R_GlobalContext->sysparent);
if (CAR(t) == R_UnboundValue)
- error("Object \"%s\" not found\n", CHAR(PRINTNAME(TAG(t))));
+ error("Object \"%s\" not found\n", CHAR(PRINTNAME(TAG(t))));
}
R_SaveToFile(s, fp, INTEGER(CADDR(args))[0]);
@@ -1811,12 +1822,12 @@
do_hdf5save (SEXP call, SEXP op, SEXP args, SEXP env)
{
errorcall(call, "HDF5 support unavailable\n");
- return(R_NilValue); /* -Wall */
+ return(R_NilValue); /* -Wall */
}
SEXP
do_hdf5load (SEXP call, SEXP op, SEXP args, SEXP env)
{
errorcall(call, "HDF5 support unavailable\n");
- return(R_NilValue); /* -Wall */
+ return(R_NilValue); /* -Wall */
}
#endif
--------------3F9F11E6B00532CFDD5A424A--
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._