diff options
author | Werner Koch <[email protected]> | 1999-01-20 18:10:35 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 1999-01-20 18:10:35 +0000 |
commit | 7debff3867c0c087ccae465517aa26e475266427 (patch) | |
tree | bcb1ccedb0ee7711cb28a6add0a16a56cf0d0c34 /g10/textfilter.c | |
parent | See ChangeLog: Tue Jan 19 19:34:58 CET 1999 Werner Koch (diff) | |
download | gnupg-7debff3867c0c087ccae465517aa26e475266427.tar.gz gnupg-7debff3867c0c087ccae465517aa26e475266427.zip |
See ChangeLog: Wed Jan 20 18:59:49 CET 1999 Werner Koch
Diffstat (limited to 'g10/textfilter.c')
-rw-r--r-- | g10/textfilter.c | 186 |
1 files changed, 148 insertions, 38 deletions
diff --git a/g10/textfilter.c b/g10/textfilter.c index 9959c9335..07630d050 100644 --- a/g10/textfilter.c +++ b/g10/textfilter.c @@ -1,5 +1,5 @@ /* textfilter.c - * Copyright (C) 1998 Free Software Foundation, Inc. + * Copyright (C) 1998,1999 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -33,7 +33,147 @@ #include "i18n.h" -#define MAX_LINELEN 20000 +#define MAX_LINELEN 19995 /* a little bit smaller than in armor.c */ + /* to make sure that a warning is displayed while */ + /* creating a message */ + +unsigned +len_without_trailing_ws( byte *line, unsigned len ) +{ + byte *p, *mark; + unsigned n; + + for(mark=NULL, p=line, n=0; n < len; n++, p++ ) { + if( strchr(" \t\r\n", *p ) ) { + if( !mark ) + mark = p; + } + else + mark = NULL; + } + + return mark? (mark - line) : len; +} + + + + +static int +standard( text_filter_context_t *tfx, IOBUF a, + byte *buf, size_t size, size_t *ret_len) +{ + int rc=0; + size_t len = 0; + unsigned maxlen; + + assert( size > 10 ); + size -= 2; /* reserve 2 bytes to append CR,LF */ + while( !rc && len < size ) { + int lf_seen; + + while( len < size && tfx->buffer_pos < tfx->buffer_len ) + buf[len++] = tfx->buffer[tfx->buffer_pos++]; + if( len >= size ) + continue; + + /* read the next line */ + maxlen = MAX_LINELEN; + tfx->buffer_pos = 0; + tfx->buffer_len = iobuf_read_line( a, &tfx->buffer, + &tfx->buffer_size, &maxlen ); + if( !maxlen ) + tfx->truncated++; + if( !tfx->buffer_len ) { + if( !len ) + rc = -1; /* eof */ + break; + } + lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n'; + tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len ); + if( lf_seen ) { + tfx->buffer[tfx->buffer_len++] = '\r'; + tfx->buffer[tfx->buffer_len++] = '\n'; + } + } + *ret_len = len; + return rc; +} + +static int +clearsign( text_filter_context_t *tfx, IOBUF a, + byte *buf, size_t size, size_t *ret_len) +{ + int rc=0; + size_t len = 0; + unsigned maxlen; + + assert( size > 2 ); + size -= 3; /* reserve for dash escaping and extra LF */ + while( !rc && len < size ) { + unsigned n; + byte *p; + + if( tfx->pending_esc ) { + buf[len++] = '-'; + buf[len++] = ' '; + tfx->pending_esc = 0; + } + while( len < size && tfx->buffer_pos < tfx->buffer_len ) + buf[len++] = tfx->buffer[tfx->buffer_pos++]; + if( len >= size ) + continue; + + /* read the next line */ + maxlen = MAX_LINELEN; + tfx->buffer_pos = 0; + tfx->buffer_len = iobuf_read_line( a, &tfx->buffer, + &tfx->buffer_size, &maxlen ); + p = tfx->buffer; + n = tfx->buffer_len; + if( !maxlen ) + tfx->truncated++; + if( !n ) { /* readline has returned eof */ + /* don't hash a pending lf here because the last one is + * not part of the signed material. OpenPGP does not + * hash the last LF because it may have to add an + * extra one in case that the original material + * does not end with one. The clear signed text + * must end in a LF, so that the following armor + * line can be detected by the parser + */ + if( !tfx->pending_lf ) { + /* make sure that the file ends with a LF */ + buf[len++] = '\n'; + if( tfx->not_dash_escaped ) + md_putc(tfx->md, '\n' ); + tfx->pending_lf = 1; + } + if( !len ) + rc = -1; /* eof */ + break; + } + if( tfx->md ) { + if( tfx->not_dash_escaped ) + md_write( tfx->md, p, n ); + else { + if( tfx->pending_lf ) { + md_putc(tfx->md, '\r' ); + md_putc(tfx->md, '\n' ); + } + md_write( tfx->md, p, len_without_trailing_ws( p, n ) ); + } + } + tfx->pending_lf = p[n-1] == '\n'; + if( tfx->not_dash_escaped ) + ; + else if( *p == '-' ) + tfx->pending_esc = 1; + else if( tfx->escape_from && n > 4 && !memcmp(p, "From ", 5 ) ) + tfx->pending_esc = 1; + } + *ret_len = len; + return rc; +} /**************** @@ -49,43 +189,11 @@ text_filter( void *opaque, int control, int rc=0; if( control == IOBUFCTRL_UNDERFLOW ) { - size_t len = 0; - unsigned maxlen; - - assert( size > 10 ); - size -= 2; /* reserve 2 bytes to append CR,LF */ - while( !rc && len < size ) { - int lf_seen; - - while( len < size && tfx->buffer_pos < tfx->buffer_len ) - buf[len++] = tfx->buffer[tfx->buffer_pos++]; - if( len >= size ) - continue; - - /* read the next line */ - maxlen = MAX_LINELEN; - tfx->buffer_pos = 0; - tfx->buffer_len = iobuf_read_line( a, &tfx->buffer, - &tfx->buffer_size, &maxlen ); - if( !maxlen ) - tfx->truncated++; - if( !tfx->buffer_len ) { - if( !len ) - rc = -1; /* eof */ - break; - } - lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n'; - tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len ); - if( lf_seen ) { - tfx->buffer[tfx->buffer_len++] = '\r'; - tfx->buffer[tfx->buffer_len++] = '\n'; - } - } - - *ret_len = len; + if( tfx->clearsign ) + rc = clearsign( tfx, a, buf, size, ret_len ); + else + rc = standard( tfx, a, buf, size, ret_len ); } - else if( control == IOBUFCTRL_DESC ) - *(char**)buf = "text_filter"; else if( control == IOBUFCTRL_FREE ) { if( tfx->truncated ) log_error(_("can't handle text lines longer than %d characters\n"), @@ -93,6 +201,8 @@ text_filter( void *opaque, int control, m_free( tfx->buffer ); tfx->buffer = NULL; } + else if( control == IOBUFCTRL_DESC ) + *(char**)buf = "text_filter"; return rc; } |