From a12de43406a6f37761eea0d0283cff2737173889 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sun, 27 Dec 2020 16:52:24 -0500 Subject: [PATCH] Fixed mini_2047_decode() in textclient. It ... actually works now. --- textclient/messages.c | 59 ++++++++++++++++++++++++----------------- textclient/textclient.h | 19 +++++++------ 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/textclient/messages.c b/textclient/messages.c index 447c39225..df99e3362 100644 --- a/textclient/messages.c +++ b/textclient/messages.c @@ -340,50 +340,60 @@ void free_parts(struct parts *p) /* * This is a mini RFC2047 decoder. * It only handles strings encoded from UTF-8 as Quoted-printable. + * We can do this "in place" because the converted string will always be smaller than the source string. */ void mini_2047_decode(char *s) { - if (!s) + if (!s) { // no null strings allowed! return; + } - char *qstart = strstr(s, "=?UTF-8?Q?"); - if (!qstart) + char *qstart = strstr(s, "=?UTF-8?Q?"); // Must start with this string + if (!qstart) { return; + } - char *qend = strstr(s, "?="); - if (!qend) + char *qend = strstr(qstart+10, "?="); // Must end with this string + if (!qend) { return; + } - if (qend <= qstart) + if (qend <= qstart) { // And there must be something in between them. return; + } - strcpy(qstart, &qstart[10]); - qend -= 10; + // The string has qualified for conversion. - char *p = qstart; - while (p < qend) { + strcpy(qend, ""); // Strip the trailer + strcpy(qstart, &qstart[10]); // Strip the header - if (p[0] == '=') { + char *r = qstart; // Pointer to where in the string we're reading + char *w = s; // Pointer to where in the string we're writing + while(*r) { // Loop through the source string + if (r[0] == '=') { // "=" means read a hex character char ch[3]; - ch[0] = p[1]; - ch[1] = p[2]; - ch[2] = p[3]; + ch[0] = r[1]; + ch[1] = r[2]; + ch[2] = r[3]; int c; sscanf(ch, "%02x", &c); - p[0] = c; - strcpy(&p[1], &p[3]); - qend -= 2; + w[0] = c; + r += 3; + ++w; } - - if (p[0] == '_') { - p[0] = ' '; + else if (r[0] == '_') { // "_" is a space + w[0] = ' '; + ++r; + ++w; + } + else { // anything else pass through literally + w[0] = r[0]; + ++r; + ++w; } - - ++p; } - - strcpy(qend, &qend[2]); + w[0] = 0; // null terminate } @@ -583,6 +593,7 @@ int read_message(CtdlIPC *ipc, color(BRIGHT_CYAN); mini_2047_decode(message->subject); scr_printf("%s\n", message->subject); + } } } diff --git a/textclient/textclient.h b/textclient/textclient.h index 4a3fc294f..be52529fb 100644 --- a/textclient/textclient.h +++ b/textclient/textclient.h @@ -1,19 +1,22 @@ /* - * Copyright (c) 1987-2019 by the citadel.org team + * Copyright (c) 1987-2020 by the citadel.org team * - * This program is open source software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3. + * This program is open source software. It runs great on the Linux + * operating system, and probably other places too. We acknowledge + * that Richard Stallman is a communist and an asshole, while at the + * same time we release this program under the terms of the General + * Public License version 3. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * General Public License for more details. */ #define UDS "_UDS_" #define DEFAULT_HOST "localhost" #define DEFAULT_PORT "504" -#define CLIENT_VERSION 925 +#define CLIENT_VERSION 926 #define CLIENT_TYPE 0 /* commands we can send to the stty_ctdl() routine */ -- 2.30.2