mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 11:32:48 -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.
This commit is contained in:
@ -490,7 +490,6 @@ int console_get_userpass_input(prompts_t *p)
|
||||
for (curr_prompt = 0; curr_prompt < p->n_prompts; curr_prompt++) {
|
||||
|
||||
DWORD savemode, newmode;
|
||||
size_t len;
|
||||
prompt_t *pr = p->prompts[curr_prompt];
|
||||
|
||||
GetConsoleMode(hin, &savemode);
|
||||
@ -503,22 +502,23 @@ int console_get_userpass_input(prompts_t *p)
|
||||
|
||||
console_write(hout, ptrlen_from_asciz(pr->prompt));
|
||||
|
||||
len = 0;
|
||||
bool failed = false;
|
||||
while (1) {
|
||||
DWORD toread = 65536;
|
||||
size_t prev_result_len = pr->result->len;
|
||||
void *ptr = strbuf_append(pr->result, toread);
|
||||
|
||||
DWORD ret = 0;
|
||||
|
||||
prompt_ensure_result_size(pr, len * 5 / 4 + 512);
|
||||
|
||||
if (!ReadFile(hin, pr->result + len, pr->resultsize - len - 1,
|
||||
&ret, NULL) || ret == 0) {
|
||||
len = (size_t)-1;
|
||||
if (!ReadFile(hin, ptr, toread, &ret, NULL) || ret == 0) {
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
len += ret;
|
||||
if (pr->result[len - 1] == '\n') {
|
||||
len--;
|
||||
if (pr->result[len - 1] == '\r')
|
||||
len--;
|
||||
|
||||
strbuf_shrink_to(pr->result, prev_result_len + ret);
|
||||
if (pr->result->s[pr->result->len - 1] == '\n') {
|
||||
strbuf_shrink_by(pr->result, 1);
|
||||
if (pr->result->s[pr->result->len - 1] == '\r')
|
||||
strbuf_shrink_by(pr->result, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -528,11 +528,9 @@ int console_get_userpass_input(prompts_t *p)
|
||||
if (!pr->echo)
|
||||
console_write(hout, PTRLEN_LITERAL("\r\n"));
|
||||
|
||||
if (len == (size_t)-1) {
|
||||
if (failed) {
|
||||
return 0; /* failure due to read error */
|
||||
}
|
||||
|
||||
pr->result[len] = '\0';
|
||||
}
|
||||
|
||||
return 1; /* success */
|
||||
|
Reference in New Issue
Block a user