Skip to content
Permalink
Browse files
document width limit on console lines, use CONSOLE_BUFFER_LENGTH in o…
…ne place.

Windows FileReadConsole could overflow its buffer (< 1024 bytes)


git-svn-id: https://svn.r-project.org/R/trunk@38967 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
ripley committed Aug 24, 2006
1 parent f6e69d1 commit 1d672a0335776e7ccd917117a85947eac53d7130
Showing 10 changed files with 47 additions and 33 deletions.
@@ -8947,7 +8947,8 @@ void Rf_endEmbeddedR(int fatal);
@noindent
which is an entry point in @file{R.dll}. Examples of its use (and a
suitable @file{Makefile.win}) can be found in the @file{tests/Embedding}
directory of the sources.
directory of the sources. You may need to ensure that
@file{@var{R_HOME}/bin} is in your @env{PATH} so the R DLLs are found.

Examples of calling @file{R.dll} directly are provided in the directory
@file{src/@/gnuwin32/@/front-ends}, including @file{Rproxy.dll} used by
@@ -475,6 +475,9 @@ command is syntactically complete. This prompt may be changed by the
user. We will generally omit the continuation prompt
and indicate continuation by simple indenting.

Command lines entered at the console are limited to 1024 bytes (not
characters): many of the consoles will not allow you to enter more.

@node Recall and correction of previous commands, Executing commands from or diverting output to a file, R commands; case sensitivity etc, Introduction and preliminaries
@section Recall and correction of previous commands

@@ -500,9 +503,9 @@ statistical system FAQ}.
@section Executing commands from or diverting output to a file
@cindex Diverting input and output

If commands are stored in an external file, say @file{commands.R} in the
working directory @file{work}, they may be executed at any time in an
@R{} session with the command
If commands@footnote{of unlimited length.} are stored in an external
file, say @file{commands.R} in the working directory @file{work}, they
may be executed at any time in an @R{} session with the command

@example
> source("commands.R")
@@ -6949,8 +6952,10 @@ skipped: this can be useful to retrieve values from it with
@end table

Note that input and output can be redirected in the usual way (using
@samp{<} and @samp{>}). Warning and error messages are sent to the
error channel (@code{stderr}) except on Windows 9X/ME.
@samp{<} and @samp{>}), but the line width limit of 1024 bytes still
applies (and lines will be truncated with no warning). Warning and error
messages are sent to the error channel (@code{stderr}) except on Windows
9X/ME.

The command @code{R CMD} allows the invocation of various tools which
are useful in conjunction with @R{}, but not intended to be called
@@ -33,6 +33,9 @@ place, so those functions are available while waiting for an event.
iconv.dll has been updated to 1.11, which has some improvements for
CJK languages under Windows (e.g. support for the Euro).

Using lines of more than 1000 chars in an R file in batch mode could
crash R.


Installing packages
-------------------
@@ -1544,7 +1544,8 @@ int consolereads(control c, char *prompt, char *buf, int len, int addtohistory)
}
cur_line[max_byte] = '\n';
cur_line[max_byte + 1] = '\0';
strcpy(buf, cur_line);
/* just to be safe: we have not allowed max_byte > len-2 */
strncpy(buf, cur_line, len);
p->r = -1;
cur_line[max_byte] = '\0';
if (max_byte && addtohistory) gl_histadd(cur_line);
@@ -258,9 +258,9 @@ ThreadedReadConsole(char *prompt, char *buf, int len, int addtohistory)
static int
CharReadConsole(char *prompt, char *buf, int len, int addtohistory)
{
int res = getline(prompt,buf,len);
if (addtohistory) gl_histadd(buf);
return !res;
int res = getline(prompt,buf,len);
if (addtohistory) gl_histadd(buf);
return !res;
}

/*3: (as InThreadReadConsole) and 4: non-interactive */
@@ -270,17 +270,16 @@ static int
FileReadConsole(char *prompt, char *buf, int len, int addhistory)
{
int ll, err = 0;
char inbuf[1001];

if (!R_Slave) {
fputs(prompt, stdout);
fflush(stdout);
}
if (fgets(inbuf, len, stdin) == NULL)
return 0;
if (fgets(buf, len, stdin) == NULL) return 0;
/* translate if necessary */
if(strlen(R_StdinEnc) && strcmp(R_StdinEnc, "native.enc")) {
size_t res, inb = strlen(inbuf), onb = len;
char *ib = inbuf, *ob = buf;
size_t res, inb = strlen(buf), onb = len;
char *ib = buf, *ob = buf;
if(!cd) {
cd = Riconv_open("", R_StdinEnc);
if(!cd) error(_("encoding '%s' is not recognised"), R_StdinEnc);
@@ -289,13 +288,14 @@ FileReadConsole(char *prompt, char *buf, int len, int addhistory)
*ob = '\0';
err = res == (size_t)(-1);
/* errors lead to part of the input line being ignored */
if(err) fputs(_("<ERROR: invalid input in encoding> "), stdout);
} else strncpy(buf, inbuf, strlen(inbuf)+1);
if(err) fputs(_("<ERROR: invalid input in encoding>\n"), stdout);
}

/* according to system.txt, should be terminated in \n, so check this
at eof or error */
ll = strlen((char *)buf);
if ((err || feof(stdin)) && buf[ll - 1] != '\n' && ll < len) {
if ((err || feof(stdin))
&& buf[ll - 1] != '\n' && ll < len) {
buf[ll++] = '\n'; buf[ll] = '\0';
}
if (!R_Interactive && !R_Slave)
@@ -630,7 +630,7 @@ void R_SetWin32(Rstart Rp)
R_CStackStart = top;
R_CStackLimit = top - bottom;
}

R_CStackDir = 1;
R_Home = Rp->rhome;
if(strlen(R_Home) >= MAX_PATH) R_Suicide("Invalid R_HOME");
@@ -939,7 +939,7 @@ int cmdlineoptions(int ac, char **av)
* Since users' expectations for save/no-save will differ, we decided
* that they should be forced to specify in the non-interactive case.
*/
if (!R_Interactive && Rp->SaveAction != SA_SAVE &&
if (!R_Interactive && Rp->SaveAction != SA_SAVE &&
Rp->SaveAction != SA_NOSAVE)
R_Suicide(_("you must specify '--save', '--no-save' or '--vanilla'"));

@@ -790,6 +790,8 @@ LibExtern AccuracyInfo R_AccuracyInfo;
#define R_FILE 2
#define R_TEXT 3

/* The maximum length of input line which will be asked for */
#define CONSOLE_BUFFER_SIZE 1024
int R_ReadConsole(char*, unsigned char*, int, int);
void R_WriteConsole(char*, int);
void R_ResetConsole(void);
@@ -59,6 +59,9 @@ source(file, local = FALSE, echo = verbose, print.eval = echo,
used a guide. If \code{encoding} has two or more elements, they are
tried in turn until the file/URL can be read without error in the
trial encoding.
Unlike input from a console, lines in the file or on a connection can
contain an unlimited number of characters.
}
\references{
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988)
@@ -1614,9 +1614,6 @@ static Rconnection newclp(char *url, char *mode)

/* ------------------- terminal connections --------------------- */

/* The size of the console buffer */
#define CONSOLE_BUFFER_SIZE 1024

static unsigned char ConsoleBuf[CONSOLE_BUFFER_SIZE];
static unsigned char *ConsoleBufp;
static int ConsoleBufCnt;
@@ -51,6 +51,7 @@ void attribute_hidden nl_Rdummy()
}
#endif


/* The 'real' main() program is in ../<SYSTEM>/system.c */
/* e.g. ../unix/system.c */

@@ -202,7 +203,8 @@ Rf_ReplIteration(SEXP rho, int savestack, int browselevel, R_ReplState *state)
if(!*state->bufp) {
R_Busy(0);
if (R_ReadConsole(R_PromptString(browselevel, state->prompt_type),
state->buf, 1024, 1) == 0) return(-1);
state->buf, CONSOLE_BUFFER_SIZE, 1) == 0)
return(-1);
state->bufp = state->buf;
}
#ifdef SHELL_ESCAPE
@@ -294,7 +296,8 @@ static void R_ReplConsole(SEXP rho, int savestack, int browselevel)

R_IoBufferWriteReset(&R_ConsoleIob);
state.buf[0] = '\0';
state.buf[1024] = '\0'; /* stopgap measure if line > 1024 chars */
state.buf[CONSOLE_BUFFER_SIZE] = '\0';
/* stopgap measure if line > CONSOLE_BUFFER_SIZE chars */
state.bufp = state.buf;
if(R_Verbose)
REprintf(" >R_ReplConsole(): before \"for(;;)\" {main.c}\n");
@@ -306,7 +309,7 @@ static void R_ReplConsole(SEXP rho, int savestack, int browselevel)
}


static unsigned char DLLbuf[1024], *DLLbufp;
static unsigned char DLLbuf[CONSOLE_BUFFER_SIZE], *DLLbufp;

void R_ReplDLLinit()
{
@@ -327,7 +330,8 @@ int R_ReplDLLdo1()

if(!*DLLbufp) {
R_Busy(0);
if (R_ReadConsole(R_PromptString(0, prompt_type), DLLbuf, 1024, 1) == 0)
if (R_ReadConsole(R_PromptString(0, prompt_type), DLLbuf,
CONSOLE_BUFFER_SIZE, 1) == 0)
return -1;
DLLbufp = DLLbuf;
}
@@ -433,12 +437,11 @@ static void win32_segv(int signum)
2005-12-17 BDR */

#define CONSOLE_BUFFER_SIZE 1024
static unsigned char ConsoleBuf[CONSOLE_BUFFER_SIZE];
static unsigned char ConsoleBuf[CONSOLE_BUFFER_SIZE];

static void sigactionSegv(int signum, siginfo_t *ip, void *context)
{
char *s, buf[1024];
char *s, buf[MAX_PATH+20];

/* First check for stack overflow if we know the stack position.
We assume anything within 16Mb beyond the stack end is a stack overflow.
@@ -568,7 +571,7 @@ static void sigactionSegv(int signum, siginfo_t *ip, void *context)
}
}
REprintf("aborting ...\n");
snprintf(buf, 1024, "rm -rf %s", R_TempDir);
snprintf(buf, MAX_PATH+20, "rm -rf %s", R_TempDir);
R_system(buf);
/* now do normal behaviour, e.g. core dump */
signal(signum, SIG_DFL);
@@ -45,7 +45,6 @@
/* The size of vector initially allocated by scan */
#define SCAN_BLOCKSIZE 1000
/* The size of the console buffer */
#define CONSOLE_BUFFER_SIZE 1024
#define CONSOLE_PROMPT_SIZE 256

#define NO_COMCHAR 100000 /* won't occur even in Unicode */

0 comments on commit 1d672a0

Please sign in to comment.