You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2013/02/08 14:00:46 UTC
svn commit: r1443996 - /subversion/trunk/subversion/libsvn_subr/prompt.c
Author: philip
Date: Fri Feb 8 13:00:46 2013
New Revision: 1443996
URL: http://svn.apache.org/r1443996
Log:
Fix a use of stack memory after function return. Interrupting a
conflict prompt caused the pool cleanup handler to access the
stack memory that was once the terminal handle.
* subversion/libsvn_subr/prompt.c
(terminal_open): Change parameter, allocate terminal handle here.
(prompt, maybe_print_realm, plaintext_prompt_helper): Use allocated
terminal handle rather than stack variable.
Modified:
subversion/trunk/subversion/libsvn_subr/prompt.c
Modified: subversion/trunk/subversion/libsvn_subr/prompt.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/prompt.c?rev=1443996&r1=1443995&r2=1443996&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/prompt.c (original)
+++ subversion/trunk/subversion/libsvn_subr/prompt.c Fri Feb 8 13:00:46 2013
@@ -146,10 +146,10 @@ terminal_close(terminal_handle_t *termin
return SVN_NO_ERROR;
}
-/* Open TERMINAL. If NOECHO is TRUE, try to turn off terminal echo.
- Use POOL for al allocations.*/
+/* Allocate and open *TERMINAL. If NOECHO is TRUE, try to turn off
+ terminal echo. Use POOL for all allocations.*/
static svn_error_t *
-terminal_open(terminal_handle_t *terminal, svn_boolean_t noecho,
+terminal_open(terminal_handle_t **terminal, svn_boolean_t noecho,
apr_pool_t *pool)
{
apr_status_t status;
@@ -161,11 +161,12 @@ terminal_open(terminal_handle_t *termina
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
+ *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
if (conin != INVALID_HANDLE_VALUE)
{
/* The process has a console. */
CloseHandle(conin);
- terminal_handle_init(terminal, NULL, NULL, noecho, FALSE, NULL);
+ terminal_handle_init(*terminal, NULL, NULL, noecho, FALSE, NULL);
return SVN_NO_ERROR;
}
#else /* !WIN32 */
@@ -176,10 +177,11 @@ terminal_open(terminal_handle_t *termina
status = apr_file_open(&tmpfd, "/dev/tty",
APR_FOPEN_READ | APR_FOPEN_WRITE,
APR_OS_DEFAULT, pool);
+ *terminal = apr_palloc(pool, sizeof(terminal_handle_t));
if (!status)
{
/* We have a terminal handle that we can use for input and output. */
- terminal_handle_init(terminal, tmpfd, tmpfd, FALSE, TRUE, pool);
+ terminal_handle_init(*terminal, tmpfd, tmpfd, FALSE, TRUE, pool);
}
#endif /* !WIN32 */
else
@@ -194,33 +196,33 @@ terminal_open(terminal_handle_t *termina
status = apr_file_open_stderr(&outfd, pool);
if (status)
return svn_error_wrap_apr(status, _("Can't open stderr"));
- terminal_handle_init(terminal, infd, outfd, FALSE, FALSE, pool);
+ terminal_handle_init(*terminal, infd, outfd, FALSE, FALSE, pool);
}
#ifdef HAVE_TERMIOS_H
/* Set terminal state */
- if (0 == apr_os_file_get(&terminal->osinfd, terminal->infd))
+ if (0 == apr_os_file_get(&(*terminal)->osinfd, (*terminal)->infd))
{
- if (0 == tcgetattr(terminal->osinfd, &terminal->attr))
+ if (0 == tcgetattr((*terminal)->osinfd, &(*terminal)->attr))
{
- struct termios attr = terminal->attr;
+ struct termios attr = (*terminal)->attr;
/* Turn off signal handling and canonical input mode */
attr.c_lflag &= ~(ISIG | ICANON);
attr.c_cc[VMIN] = 1; /* Read one byte at a time */
attr.c_cc[VTIME] = 0; /* No timeout, wait indefinitely */
if (noecho)
attr.c_lflag &= ~(ECHO); /* Turn off echo */
- if (0 == tcsetattr(terminal->osinfd, TCSAFLUSH, &attr))
+ if (0 == tcsetattr((*terminal)->osinfd, TCSAFLUSH, &attr))
{
- terminal->noecho = noecho;
- terminal->restore_state = TRUE;
+ (*terminal)->noecho = noecho;
+ (*terminal)->restore_state = TRUE;
}
}
}
#endif /* HAVE_TERMIOS_H */
/* Register pool cleanup to close handles and restore echo state. */
- apr_pool_cleanup_register(terminal->pool, terminal,
+ apr_pool_cleanup_register((*terminal)->pool, *terminal,
terminal_plain_cleanup,
terminal_child_cleanup);
return SVN_NO_ERROR;
@@ -437,16 +439,16 @@ prompt(const char **result,
svn_boolean_t saw_first_half_of_eol = FALSE;
svn_stringbuf_t *strbuf = svn_stringbuf_create_empty(pool);
- terminal_handle_t terminal;
+ terminal_handle_t *terminal;
int code;
char c;
SVN_ERR(terminal_open(&terminal, hide, pool));
- SVN_ERR(terminal_puts(prompt_msg, &terminal, pool));
+ SVN_ERR(terminal_puts(prompt_msg, terminal, pool));
while (1)
{
- SVN_ERR(terminal_getc(&code, &terminal, (strbuf->len > 0), pool));
+ SVN_ERR(terminal_getc(&code, terminal, (strbuf->len > 0), pool));
/* Check for cancellation after a character has been read, some
input processing modes may eat ^C and we'll only notice a
@@ -477,7 +479,7 @@ prompt(const char **result,
case TERMINAL_EOF:
return svn_error_create(
APR_EOF,
- terminal_close(&terminal),
+ terminal_close(terminal),
_("End of file while reading from terminal"));
default:
@@ -512,13 +514,13 @@ prompt(const char **result,
svn_stringbuf_appendbyte(strbuf, c);
}
- if (terminal.noecho)
+ if (terminal->noecho)
{
/* If terminal echo was turned off, make sure future output
to the terminal starts on a new line, as expected. */
- terminal_puts(APR_EOL_STR, &terminal, pool);
+ terminal_puts(APR_EOL_STR, terminal, pool);
}
- SVN_ERR(terminal_close(&terminal));
+ SVN_ERR(terminal_close(terminal));
return svn_cmdline_cstring_to_utf8(result, strbuf->data, pool);
}
@@ -536,13 +538,13 @@ maybe_print_realm(const char *realm, apr
{
if (realm)
{
- terminal_handle_t terminal;
+ terminal_handle_t *terminal;
SVN_ERR(terminal_open(&terminal, FALSE, pool));
SVN_ERR(terminal_puts(
apr_psprintf(pool,
_("Authentication realm: %s\n"), realm),
- &terminal, pool));
- SVN_ERR(terminal_close(&terminal));
+ terminal, pool));
+ SVN_ERR(terminal_close(terminal));
}
return SVN_NO_ERROR;
@@ -757,7 +759,7 @@ plaintext_prompt_helper(svn_boolean_t *m
svn_boolean_t answered = FALSE;
svn_cmdline_prompt_baton2_t *pb = baton;
const char *config_path = NULL;
- terminal_handle_t terminal;
+ terminal_handle_t *terminal;
if (pb)
SVN_ERR(svn_config_get_user_config_path(&config_path, pb->config_dir,
@@ -766,8 +768,8 @@ plaintext_prompt_helper(svn_boolean_t *m
SVN_ERR(terminal_open(&terminal, FALSE, pool));
SVN_ERR(terminal_puts(apr_psprintf(pool, prompt_text,
realmstring, config_path),
- &terminal, pool));
- SVN_ERR(terminal_close(&terminal));
+ terminal, pool));
+ SVN_ERR(terminal_close(terminal));
do
{