From 7590d0625ba6e994a00191aa708d3aadee70c407 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 22 Jan 2020 22:24:41 +0000 Subject: [PATCH] Introduce and use strbuf_chomp. Those chomp operations in wincons.c and uxcons.c looked ugly, and I'm not totally convinced they couldn't underrun the buffer by 1 byte in weird circumstances. strbuf_chomp is neater. --- misc.h | 1 + scpserver.c | 2 +- unix/uxcons.c | 4 +--- utils.c | 9 +++++++++ windows/wincons.c | 6 ++---- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/misc.h b/misc.h index dfc6659d..51155a21 100644 --- a/misc.h +++ b/misc.h @@ -79,6 +79,7 @@ char *strbuf_to_str(strbuf *buf); /* does free buf, but you must free result */ void strbuf_catf(strbuf *buf, const char *fmt, ...); void strbuf_catfv(strbuf *buf, const char *fmt, va_list ap); static inline void strbuf_clear(strbuf *buf) { strbuf_shrink_to(buf, 0); } +bool strbuf_chomp(strbuf *buf, char char_to_remove); strbuf *strbuf_new_for_agent_query(void); void strbuf_finalise_agent_query(strbuf *buf); diff --git a/scpserver.c b/scpserver.c index 3123dc16..e594f1ab 100644 --- a/scpserver.c +++ b/scpserver.c @@ -1095,7 +1095,7 @@ static void scp_sink_coroutine(ScpSink *scp) /* * Parse the command. */ - strbuf_shrink_by(scp->command, 1); /* chomp the newline */ + strbuf_chomp(scp->command, '\n'); scp->command_chr = scp->command->len > 0 ? scp->command->s[0] : '\0'; if (scp->command_chr == 'T') { unsigned long dummy1, dummy2; diff --git a/unix/uxcons.c b/unix/uxcons.c index 3e8a7ea5..da7b8935 100644 --- a/unix/uxcons.c +++ b/unix/uxcons.c @@ -592,10 +592,8 @@ int console_get_userpass_input(prompts_t *p) } 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 (strbuf_chomp(pr->result, '\n')) break; - } } tcsetattr(infd, TCSANOW, &oldmode); diff --git a/utils.c b/utils.c index 667281d6..5acb53cb 100644 --- a/utils.c +++ b/utils.c @@ -443,6 +443,15 @@ void strbuf_shrink_by(strbuf *buf, size_t amount_to_remove) buf->s[buf->len] = '\0'; } +bool strbuf_chomp(strbuf *buf, char char_to_remove) +{ + if (buf->len > 0 && buf->s[buf->len-1] == char_to_remove) { + strbuf_shrink_by(buf, 1); + return true; + } + return false; +} + static void strbuf_BinarySink_write( BinarySink *bs, const void *data, size_t len) { diff --git a/windows/wincons.c b/windows/wincons.c index d91d9cef..4fb5eb3f 100644 --- a/windows/wincons.c +++ b/windows/wincons.c @@ -515,10 +515,8 @@ int console_get_userpass_input(prompts_t *p) } 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); + if (strbuf_chomp(pr->result, '\n')) { + strbuf_chomp(pr->result, '\r'); break; } }