1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-06 22:12:47 -05:00

Use strbuf to store results in prompts_t.

UBsan pointed out another memcpy from NULL (again with length 0) in
the prompts_t system. When I looked at it, I realised that firstly
prompt_ensure_result_size was an early not-so-good implementation of
sgrowarray_nm that would benefit from being replaced with a call to
the real one, and secondly, the whole system for storing prompt
results should really have been replaced with strbufs with the no-move
option, because that's doing all the same jobs better.

So, now each prompt_t holds a strbuf in place of its previous manually
managed string. prompt_ensure_result_size is gone (the console
prompt-reading functions use strbuf_append, and everything else just
adds to the strbuf in the usual marshal.c way). New functions exist to
retrieve a prompt_t's result, either by reference or copied.

(cherry picked from commit cd6bc14f04)
This commit is contained in:
Simon Tatham
2020-01-21 20:19:47 +00:00
parent 34a0460f05
commit 697cfa5b7f
10 changed files with 80 additions and 107 deletions

View File

@ -7156,7 +7156,6 @@ char *term_get_ttymode(Terminal *term, const char *mode)
struct term_userpass_state {
size_t curr_prompt;
bool done_prompt; /* printed out prompt yet? */
size_t pos; /* cursor position */
};
/* Tiny wrapper to make it easier to write lots of little strings */
@ -7211,7 +7210,6 @@ int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input)
if (!s->done_prompt) {
term_write(term, ptrlen_from_asciz(pr->prompt));
s->done_prompt = true;
s->pos = 0;
}
/* Breaking out here ensures that the prompt is printed even
@ -7226,8 +7224,6 @@ int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input)
case 10:
case 13:
term_write(term, PTRLEN_LITERAL("\r\n"));
prompt_ensure_result_size(pr, s->pos + 1);
pr->result[s->pos] = '\0';
/* go to next prompt, if any */
s->curr_prompt++;
s->done_prompt = false;
@ -7235,18 +7231,18 @@ int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input)
break;
case 8:
case 127:
if (s->pos > 0) {
if (pr->result->len > 0) {
if (pr->echo)
term_write(term, PTRLEN_LITERAL("\b \b"));
s->pos--;
strbuf_shrink_by(pr->result, 1);
}
break;
case 21:
case 27:
while (s->pos > 0) {
while (pr->result->len > 0) {
if (pr->echo)
term_write(term, PTRLEN_LITERAL("\b \b"));
s->pos--;
strbuf_shrink_by(pr->result, 1);
}
break;
case 3:
@ -7264,8 +7260,7 @@ int term_get_userpass_input(Terminal *term, prompts_t *p, bufchain *input)
*/
if (!pr->echo || (c >= ' ' && c <= '~') ||
((unsigned char) c >= 160)) {
prompt_ensure_result_size(pr, s->pos + 1);
pr->result[s->pos++] = c;
put_byte(pr->result, c);
if (pr->echo)
term_write(term, make_ptrlen(&c, 1));
}