From 4944b4ddd5dfb00c2b573887c6f4919c40c9391a Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 21 Dec 2021 13:25:19 +0000 Subject: [PATCH] Remove duplicated string-literal formatter in Telnet proxy. Now it's done using the same code as in write_c_string_literal(), by means of factoring the latter into a version that targets any old BinarySink and a convenience wrapper taking a FILE *. --- marshal.h | 5 +++++ proxy/telnet.c | 19 +------------------ utils/write_c_string_literal.c | 30 +++++++++++++++++++----------- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/marshal.h b/marshal.h index 515f0e53..4d5b0075 100644 --- a/marshal.h +++ b/marshal.h @@ -152,6 +152,10 @@ struct BinarySink { #define put_fmtv(bs, fmt, ap) \ BinarySink_put_fmtv(BinarySink_UPCAST(bs), fmt, ap) +/* More complicated function implemented in write_c_string_literal.c */ +#define put_c_string_literal(bs, str) \ + BinarySink_put_c_string_literal(BinarySink_UPCAST(bs), str) + /* * The underlying real C functions that implement most of those * macros. Generally you won't want to call these directly, because @@ -180,6 +184,7 @@ void BinarySink_put_mp_ssh1(BinarySink *bs, mp_int *x); void BinarySink_put_mp_ssh2(BinarySink *bs, mp_int *x); void BinarySink_put_fmt(BinarySink *, const char *fmt, ...) PRINTF_LIKE(2, 3); void BinarySink_put_fmtv(BinarySink *, const char *fmt, va_list ap); +void BinarySink_put_c_string_literal(BinarySink *, ptrlen); /* ---------------------------------------------------------------------- */ diff --git a/proxy/telnet.c b/proxy/telnet.c index e0a54450..1b4a5326 100644 --- a/proxy/telnet.c +++ b/proxy/telnet.c @@ -336,25 +336,8 @@ static void proxy_telnet_process_queue(ProxyNegotiator *pn) pn->ps->remote_addr, pn->ps->remote_port, s->conf, NULL); strbuf *logmsg = strbuf_new(); - const char *in; - put_datapl(logmsg, PTRLEN_LITERAL("Sending Telnet proxy command: ")); - - for (in = censored_cmd; *in; in++) { - if (*in == '\n') { - put_datapl(logmsg, PTRLEN_LITERAL("\\n")); - } else if (*in == '\r') { - put_datapl(logmsg, PTRLEN_LITERAL("\\r")); - } else if (*in == '\t') { - put_datapl(logmsg, PTRLEN_LITERAL("\\t")); - } else if (*in == '\\') { - put_datapl(logmsg, PTRLEN_LITERAL("\\\\")); - } else if (0x20 <= *in && *in < 0x7F) { - put_byte(logmsg, *in); - } else { - put_fmt(logmsg, "\\x%02X", (unsigned)*in & 0xFF); - } - } + put_c_string_literal(logmsg, ptrlen_from_asciz(censored_cmd)); plug_log(pn->ps->plug, PLUGLOG_PROXY_MSG, NULL, 0, logmsg->s, 0); strbuf_free(logmsg); diff --git a/utils/write_c_string_literal.c b/utils/write_c_string_literal.c index 6415c287..e8b2f53b 100644 --- a/utils/write_c_string_literal.c +++ b/utils/write_c_string_literal.c @@ -1,31 +1,39 @@ /* - * Write data to a file in the form of a C string literal, with any - * non-printable-ASCII character escaped appropriately. + * Write data to a file or BinarySink in the form of a C string + * literal, with any non-printable-ASCII character escaped + * appropriately. */ #include "defs.h" #include "misc.h" -void write_c_string_literal(FILE *fp, ptrlen str) +void BinarySink_put_c_string_literal(BinarySink *bs, ptrlen str) { for (const char *p = str.ptr; p < (const char *)str.ptr + str.len; p++) { char c = *p; if (c == '\n') - fputs("\\n", fp); + put_datalit(bs, "\\n"); else if (c == '\r') - fputs("\\r", fp); + put_datalit(bs, "\\r"); else if (c == '\t') - fputs("\\t", fp); + put_datalit(bs, "\\t"); else if (c == '\b') - fputs("\\b", fp); + put_datalit(bs, "\\b"); else if (c == '\\') - fputs("\\\\", fp); + put_datalit(bs, "\\\\"); else if (c == '"') - fputs("\\\"", fp); + put_datalit(bs, "\\\""); else if (c >= 32 && c <= 126) - fputc(c, fp); + put_byte(bs, c); else - fprintf(fp, "\\%03o", (unsigned char)c); + put_fmt(bs, "\\%03o", (unsigned)c & 0xFFU); } } + +void write_c_string_literal(FILE *fp, ptrlen str) +{ + stdio_sink s; + stdio_sink_init(&s, fp); + put_c_string_literal(&s, str); +}