# HG changeset patch # User Mychaela Falconia # Date 1683363732 0 # Node ID 612c4d0df7681ac3283465aecc883be9118e2cb7 # Parent 7a6cd16689f50da7a8210705ca0c9e199c5fb1b2 f-demime: rework for unboundedly long lines diff -r 7a6cd16689f5 -r 612c4d0df768 f-demime/defs.h --- a/f-demime/defs.h Sat May 06 06:41:20 2023 +0000 +++ b/f-demime/defs.h Sat May 06 09:02:12 2023 +0000 @@ -5,6 +5,7 @@ enum msg_state { MSG_STATE_UNDEF, /* before From line */ + MSG_STATE_DELIM_UNTERM, /* unterminated previous delimiter line */ MSG_STATE_HEADER, /* message or body part header */ MSG_STATE_BODY_PASS, /* body pass-through state */ MSG_STATE_PTEXT_B64, /* text/plain decoding from base64 */ diff -r 7a6cd16689f5 -r 612c4d0df768 f-demime/finish.c --- a/f-demime/finish.c Sat May 06 06:41:20 2023 +0000 +++ b/f-demime/finish.c Sat May 06 09:02:12 2023 +0000 @@ -32,10 +32,16 @@ { switch (msg_state) { case MSG_STATE_HEADER: - if (got_cont_type) + if (got_cont_type) { fputs(cont_type_buf, stdout); - if (got_cont_te) + if (cont_type_buf[strlen(cont_type_buf)-1] != '\n') + putchar('\n'); + } + if (got_cont_te) { fputs(cont_te_buf, stdout); + if (cont_te_buf[strlen(cont_te_buf)-1] != '\n') + putchar('\n'); + } return; case MSG_STATE_PTEXT_B64: base64_dec_finish(); diff -r 7a6cd16689f5 -r 612c4d0df768 f-demime/header.c --- a/f-demime/header.c Sat May 06 06:41:20 2023 +0000 +++ b/f-demime/header.c Sat May 06 09:02:12 2023 +0000 @@ -27,7 +27,7 @@ got_cont_te = 0; } printf("X-Fdemime-Error: %s\n", msg); - puts(line); + fputs(line, stdout); hdr_state = HDR_STATE_ERROR; } @@ -49,31 +49,31 @@ error(line, "continuation line at the beginning of header"); return; case HDR_STATE_GOTSOME: - puts(line); + fputs(line, stdout); return; case HDR_STATE_CONT_TYPE: prev_len = strlen(cont_type_buf); - if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) { + if (prev_len + strlen(line) + 1 > HDR_BUF_SIZE) { error_ct_cont("Content-Type"); fputs(cont_type_buf, stdout); - puts(line); + fputs(line, stdout); hdr_state = HDR_STATE_ERROR; got_cont_type = 0; return; } - sprintf(cont_type_buf + prev_len, "%s\n", line); + strcpy(cont_type_buf + prev_len, line); return; case HDR_STATE_CONT_TE: prev_len = strlen(cont_te_buf); - if (prev_len + strlen(line) + 2 > HDR_BUF_SIZE) { + if (prev_len + strlen(line) + 1 > HDR_BUF_SIZE) { error_ct_cont("Content-Transfer-Encoding"); fputs(cont_te_buf, stdout); - puts(line); + fputs(line, stdout); hdr_state = HDR_STATE_ERROR; got_cont_te = 0; return; } - sprintf(cont_te_buf + prev_len, "%s\n", line); + strcpy(cont_te_buf + prev_len, line); return; default: fprintf(stderr, @@ -83,21 +83,21 @@ } void -header_input_line(line) +header_input_line(line, unterm, prev_unterm) char *line; { char *cp, savech; enum msg_hdr_state newhdr; - if (!line[0]) { + if (!prev_unterm && line[0] == '\n') { process_header_end(); return; } if (hdr_state == HDR_STATE_ERROR) { - puts(line); + fputs(line, stdout); return; } - if (line[0] == ' ' || line[0] == '\t') { + if (prev_unterm || line[0] == ' ' || line[0] == '\t') { cont_line(line); return; } @@ -127,7 +127,7 @@ error(line, "duplicate Content-Type"); return; } - sprintf(cont_type_buf, "%s\n", line); + strcpy(cont_type_buf, line); got_cont_type = 1; break; case HDR_STATE_CONT_TE: @@ -135,11 +135,11 @@ error(line, "duplicate Content-Transfer-Encoding"); return; } - sprintf(cont_te_buf, "%s\n", line); + strcpy(cont_te_buf, line); got_cont_te = 1; break; default: - puts(line); + fputs(line, stdout); } hdr_state = newhdr; } diff -r 7a6cd16689f5 -r 612c4d0df768 f-demime/main.c --- a/f-demime/main.c Sat May 06 06:41:20 2023 +0000 +++ b/f-demime/main.c Sat May 06 09:02:12 2023 +0000 @@ -15,7 +15,6 @@ #include "defs.h" char *att_filename_buf, *att_filename_base, *att_filename_tail; -unsigned input_lineno; static void get_attachment_dir() @@ -60,7 +59,9 @@ main(argc, argv) char **argv; { - char linebuf[LINE_BUF_SIZE], *cp; + char linebuf[LINE_BUF_SIZE]; + int c, unterm, prev_unterm; + unsigned lineno; if (argc > 3) { fprintf(stderr, "usage: %s [infile [outfile]]\n", argv[0]); @@ -75,25 +76,34 @@ perror(argv[2]); exit(1); } - for (input_lineno = 1; fgets(linebuf, sizeof linebuf, stdin); - input_lineno++) { - cp = index(linebuf, '\n'); - if (cp) { - *cp = '\0'; - if (cp > linebuf && cp[-1] == '\r') - *--cp = '\0'; - } else { - fprintf(stderr, - "f-demime warning: input line %u too long or unterminated\n", - input_lineno); - } - if (!strncmp(linebuf, "From ", 5)) { + lineno = 0; + for (prev_unterm = 0; fgets(linebuf, sizeof linebuf, stdin); + prev_unterm = unterm) { + if (!prev_unterm) + lineno++; + if (index(linebuf, '\n')) + unterm = 0; + else + unterm = 1; + if (!prev_unterm && !strncmp(linebuf, "From ", 5)) { finish_msg_body(); - puts(linebuf); + fputs(linebuf, stdout); + if (unterm) { + fprintf(stderr, + "f-demime warning: From line %u too long or unterminated\n", + lineno); + for (;;) { + c = getchar(); + if (c == EOF || c == '\n') + break; + } + putchar('\n'); + unterm = 0; + } begin_new_message(); continue; } - message_input_line(linebuf); + message_input_line(linebuf, unterm, prev_unterm); } finish_msg_body(); exit(0); diff -r 7a6cd16689f5 -r 612c4d0df768 f-demime/msgstate.c --- a/f-demime/msgstate.c Sat May 06 06:41:20 2023 +0000 +++ b/f-demime/msgstate.c Sat May 06 09:02:12 2023 +0000 @@ -47,7 +47,7 @@ } static int -check_mp_terminator(line) +check_mp_terminator(line, unterm) char *line; { unsigned lev, bndlen; @@ -61,15 +61,19 @@ if (strncmp(line+2, bnd, bndlen)) continue; finish_msg_body(); - puts(line); + fputs(line, stdout); cp = line + 2 + bndlen; if (!*cp || isspace(*cp)) { mp_nest_level = lev + 1; start_entity_hdr(); + if (unterm) + msg_state = MSG_STATE_DELIM_UNTERM; return(1); } - if (cp[0] != '-' || cp[1] != '-') - puts("X-Fdemime-Error: invalid delimiter line"); + if (cp[0] != '-' || cp[1] != '-') { + if (!unterm) + puts("X-Fdemime-Error: invalid delimiter line"); + } mp_nest_level = lev; msg_state = MSG_STATE_BODY_PASS; return(1); @@ -78,21 +82,26 @@ } void -message_input_line(line) +message_input_line(line, unterm, prev_unterm) char *line; { - if (check_mp_terminator(line)) + if (!prev_unterm && check_mp_terminator(line, unterm)) return; switch (msg_state) { case MSG_STATE_UNDEF: emit_prefrom_warning(); - puts(line); + fputs(line, stdout); + return; + case MSG_STATE_DELIM_UNTERM: + fputs(line, stdout); + if (!unterm) + msg_state = MSG_STATE_HEADER; return; case MSG_STATE_HEADER: - header_input_line(line); + header_input_line(line, unterm, prev_unterm); return; case MSG_STATE_BODY_PASS: - puts(line); + fputs(line, stdout); return; case MSG_STATE_PTEXT_B64: case MSG_STATE_BLOB_B64: @@ -100,7 +109,7 @@ base64_input_line(line); return; case MSG_STATE_PTEXT_QP: - qpdec_input_line(line); + qpdec_input_line(line, unterm); return; default: fprintf(stderr, diff -r 7a6cd16689f5 -r 612c4d0df768 f-demime/qpdec.c --- a/f-demime/qpdec.c Sat May 06 06:41:20 2023 +0000 +++ b/f-demime/qpdec.c Sat May 06 09:02:12 2023 +0000 @@ -48,7 +48,7 @@ } void -qpdec_input_line(line) +qpdec_input_line(line, unterm) char *line; { char *cp; @@ -61,8 +61,11 @@ dec_outf(c); continue; } - if (!*cp) + if (!*cp) { + if (unterm) + qpdec_err_flag = 1; return; + } if (isxdigit(cp[0]) && isxdigit(cp[1])) { c = decode_hex_byte(cp); cp += 2; @@ -72,5 +75,6 @@ qpdec_err_flag = 1; dec_outf('='); } - dec_outf('\n'); + if (!unterm) + dec_outf('\n'); }