Package: trn
Version: 3.6-16
Severity: normal
Tags: patch

When presented with an overlong References: line trn copies it into a
fixed length buffer which often causes a reference to become
truncated.

e.g:

Message-ID: <[EMAIL PROTECTED]>
References: <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL 
PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL 
PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL 
PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <[EMAIL 
PROTECTED]>

becomes:

References: <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> <xxxxxxxxx <[EMAIL 
PROTECTED]>

on reply.

I believe this patch fixes the bug without introducing any new ones:

diff -u old-trn/trn-3.6/intrp.c trn-3.6/intrp.c
--- old-trn/trn-3.6/intrp.c     1994-11-10 10:30:06.000000000 +0000
+++ trn-3.6/intrp.c     2008-06-17 12:09:10.000000000 +0100
@@ -868,8 +868,23 @@
                    if (in_ng) {
                        parseheader(art);
                        if (htype[REFS_LINE].ht_minpos >= 0) {
+                           int trial_size=sizeof(scrbuf);
+                            char * trial_buf=0;
+
                            refs_buf = fetchlines(art,REFS_LINE);
-                           refscpy(scrbuf,(sizeof scrbuf),refs_buf);
+                           do {
+                             if (trial_buf != 0) trial_size = trial_size*2;
+                             free(trial_buf);
+                             trial_buf = malloc(trial_size);
+                           } while (refscpy(trial_buf,trial_size,refs_buf) < 
1);
+                           if (strlen(trial_buf)+1 < (sizeof scrbuf)) {
+                             strcpy(scrbuf, trial_buf);
+                           }
+                           else {
+                             reducerefs(scrbuf,(sizeof scrbuf),trial_buf);
+                           }
+
+                           free(trial_buf);                    
                        }
                        else
                            *scrbuf = '\0';
@@ -885,21 +900,18 @@
                    }
                    parseheader(art);
                    if (htype[REFS_LINE].ht_minpos >= 0) {
+                       int trial_size=sizeof(scrbuf);
+                       char * trial_buf=0;
+
                        refs_buf = fetchlines(art,REFS_LINE);
-                       refscpy(scrbuf,(sizeof scrbuf),refs_buf);
-                       /* no more than 3 prior references PLUS the
-                       ** root article allowed, including the one
-                       ** concatenated below */
-                       if ((s = rindex(scrbuf,'<')) > scrbuf) {
-                           *s = '\0';
-                           h = rindex(scrbuf,'<');
-                           *s = '<';
-                           if (h > scrbuf) {
-                               s = index(scrbuf+1,'<');
-                               if (s < h)
-                                   strcpy(s,h);
-                           }
-                       }
+
+                       do {
+                         if (trial_buf != 0) trial_size = trial_size*2;
+                         free(trial_buf);
+                         trial_buf = malloc(trial_size);
+                       } while (refscpy(trial_buf,trial_size,refs_buf) < 1);
+                       reducerefs(scrbuf,(sizeof scrbuf),trial_buf);
+                       free(trial_buf);
                    }
                    else
                        *scrbuf = '\0';
@@ -1247,7 +1259,7 @@
 
 /* copy a references line, normalizing as we go */
 
-void
+int
 refscpy(dest,destsize,src)
 register char *dest, *src;
 register int destsize;
@@ -1300,8 +1312,49 @@
            *dest++ = ' ';
     }
     *dest = '\0';
+    return(destsize);
 } 
 
+/* reduce a references line */
+/* note, modifies src */
+void
+reducerefs(dest,destsize,src)
+register char *dest, *src;
+register int destsize;
+{
+  char * s;
+  char * h;
+  /* no more than 3 prior references PLUS the
+  ** root article allowed, including the one
+  ** concatenated below */
+  if ((s = rindex(src,'<')) > src) {
+    *s = '\0';
+    h = rindex(src,'<');
+    *s = '<';
+    if (h > src) {
+      s = index(src+1,'<');
+      if (s < h)
+       strcpy(s,h);
+    }
+  }
+  if (strlen(src) < destsize) {
+    strcpy(dest,src);
+  }
+  else {
+    if ((s = rindex(src,'<')) > src) {
+      if (strlen(s) < destsize) {
+       strcpy(dest,s);
+      }
+      else {
+       *dest = '\0';
+      }
+    }
+    else {
+      *dest = '\0';
+    }
+  }
+}
+
 /* get the person's real name from /etc/passwd */
 /* (string is overwritten, so it must be copied) */
 
diff -u old-trn/trn-3.6/intrp.h trn-3.6/intrp.h
--- old-trn/trn-3.6/intrp.h     1994-10-18 00:16:29.000000000 +0100
+++ trn-3.6/intrp.h     2008-06-17 11:49:57.000000000 +0100
@@ -33,5 +33,6 @@
 char   *filexp _((char*));
 char   *dointerp _((char*,int,char*,char*));
 void   interp _((char*,int,char*));
-void   refscpy _((char*,int,char*));
+int    refscpy _((char*,int,char*));
+void   reducerefs _((char*,int,char*));
 char   *getrealname _((long));


-- System Information:
Debian Release: 3.1
Architecture: i386 (i686)
Kernel: Linux 2.6.16.60
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages trn depends on:
ii  inewsinn [inews]      1:1.7.2-19         NNTP client news injector, from In
ii  libc6                 2.3.2.ds1-22sarge6 GNU C Library: Shared libraries an
ii  libncurses5           5.4-4              Shared libraries for terminal hand

-- no debconf information



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to