package fontforge
tags 590844 + patch
thanks

The problem is at GFileGetAbsoluteName() in gutils/fsys.c, where strcpy() is
used to move strings between overlapping memory:

---8<---
        /* Normalize out any .. */
        spt = rpt = buffer;
        while ( *spt!='\0' ) {
            if ( *spt=='/' ) ++spt;
            for ( pt = spt; *pt!='\0' && *pt!='/'; ++pt );
            if ( pt==spt )      /* Found // in a path spec, reduce to / (we've*/
-->             strcpy(spt,pt); /*  skipped past the :// of the machine name) */
            else if ( pt==spt+1 && spt[0]=='.' )        /* Noop */
-->             strcpy(spt,pt);
            else if ( pt==spt+2 && spt[0]=='.' && spt[1]=='.' ) {
                for ( bpt=spt-2 ; bpt>rpt && *bpt!='/'; --bpt );
                if ( bpt>=rpt && *bpt=='/' ) {
-->                 strcpy(bpt,pt);
                    spt = bpt;
                } else {
                    rpt = pt;
                    spt = pt;
                }
            } else
                spt = pt;
        }
---8<---

I've verified this by inserting a printf to dump the result, and it resolve my
command line argument '../../tlwg/TlwgMono-BoldOblique.sfd' as
'/path/to/the/common/root/tlon/TlwgMono-BoldOblique.sfd'. Note that 'tlwg' is
overwritten and becomes 'tlon'.

Using memmove() instead fixes this. Proposed patch is attached.
Index: fontforge-0.0.20090923/gutils/fsys.c
===================================================================
--- fontforge-0.0.20090923.orig/gutils/fsys.c	2010-07-29 21:37:08.617913843 +0700
+++ fontforge-0.0.20090923/gutils/fsys.c	2010-07-29 21:59:28.638414475 +0700
@@ -62,13 +62,13 @@
 	    if ( *spt=='/' ) ++spt;
 	    for ( pt = spt; *pt!='\0' && *pt!='/'; ++pt );
 	    if ( pt==spt )	/* Found // in a path spec, reduce to / (we've*/
-		strcpy(spt,pt); /*  skipped past the :// of the machine name) */
+		memmove(spt,pt,strlen(pt)+1); /*  skipped past the :// of the machine name) */
 	    else if ( pt==spt+1 && spt[0]=='.' )	/* Noop */
-		strcpy(spt,pt);
+		memmove(spt,pt,strlen(pt)+1);
 	    else if ( pt==spt+2 && spt[0]=='.' && spt[1]=='.' ) {
 		for ( bpt=spt-2 ; bpt>rpt && *bpt!='/'; --bpt );
 		if ( bpt>=rpt && *bpt=='/' ) {
-		    strcpy(bpt,pt);
+		    memmove(bpt,pt,strlen(pt)+1);
 		    spt = bpt;
 		} else {
 		    rpt = pt;

Reply via email to