pop-tag-mark crashes when the buffer's directory is different from mg's
cwd. Steps to reproduce...

generate some tags :
# cd /usr/src/usr.bin/mg && cvs up && make && make install
# cd /usr/src/sys && make tags
use them :
# mg /usr/src/sys/dev/softraid_crypto.c (for example)
then M-x visit-tag-table give /usr/src/sys/arch/i386/tags
put the cursor on sr_workunit then M-. which arrives at softraidvar.h
and then follow scsi_xfer which puts you in scsiconf.h,
then M-*, mg crashes with core dump.

Record absolute filename while pushing onto stack. comments?

Index: tags.c
===================================================================
RCS file: /home/sunil/cvs/src/usr.bin/mg/tags.c,v
retrieving revision 1.1
diff -u -p -r1.1 tags.c
--- tags.c      28 Nov 2011 04:41:39 -0000      1.1
+++ tags.c      1 Dec 2011 19:42:09 -0000
@@ -208,7 +208,7 @@ pushtag(char *tok)
 {
        struct ctag *res;
        struct tagpos *s;
-       char *bname;
+       char bname[NFILEN];
        int doto, dotline;
        
        if ((res = searchtag(tok)) == NULL)
@@ -216,7 +216,17 @@ pushtag(char *tok)
                
        doto = curwp->w_doto;
        dotline = curwp->w_dotline;
-       bname = curbp->b_bname;
+       /* record absolute filenames. Fixes issues when mg's cwd is not the
+        * same as buffer's directory.
+        */
+       if (strlcpy(bname, curbp->b_cwd, sizeof(bname)) >= sizeof(bname)) {
+                   ewprintf("filename too long");
+                   return (FALSE);
+       }
+       if (strlcat(bname, curbp->b_bname, sizeof(bname)) >= sizeof(bname)) {
+                   ewprintf("filename too long");
+                   return (FALSE);
+       }       
 
        if (loadbuffer(res->fname) == FALSE)
                return (FALSE);
@@ -227,8 +237,8 @@ pushtag(char *tok)
                        return (FALSE);
                }
                if ((s->bname = strdup(bname)) == NULL) {
-                           ewprintf("Out of memory");
-                           return (FALSE);
+                       ewprintf("Out of memory");
+                       return (FALSE);
                }
                s->doto = doto;
                s->dotline = dotline;

Reply via email to