]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcstr.c
Using uninitialized (and wrong) variable in FcStrCopyFilename.
[fontconfig.git] / src / fcstr.c
index b60c082b2be06bd2ea5c3a46db5e1b176425c7be..5faf5790f8ba4e9dd3f1522b0109f16a73e4e8f2 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "fcint.h"
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
-#include "fcint.h"
 
 FcChar8 *
 FcStrCopy (const FcChar8 *s)
 {
-    FcChar8    *r;
+    int     len;
+    FcChar8 *r;
 
     if (!s)
        return 0;
-    r = (FcChar8 *) malloc (strlen ((char *) s) + 1);
+    len = strlen ((char *) s) + 1;
+    r = (FcChar8 *) malloc (len);
     if (!r)
        return 0;
-    FcMemAlloc (FC_MEM_STRING, strlen ((char *) s) + 1);
-    strcpy ((char *) r, (char *) s);
+    FcMemAlloc (FC_MEM_STRING, len);
+    memcpy (r, s, len);
     return r;
 }
 
@@ -449,8 +451,7 @@ again:
        ++ s1;
        ++ s2;
     }
-
-    return 0;
+    /* never reached. */
 }
 
 int
@@ -707,7 +708,7 @@ FcStrBufChar (FcStrBuf *buf, FcChar8 c)
        }
        else
        {
-           size = buf->size + 1024;
+           size = buf->size + 64;
            new = malloc (size);
            if (new)
            {
@@ -763,26 +764,21 @@ FcStrCopyFilename (const FcChar8 *s)
     if (*s == '~')
     {
        FcChar8 *home = FcConfigHome ();
+       FcChar8 *full;
        int     size;
        if (!home)
            return 0;
        size = strlen ((char *) home) + strlen ((char *) s);
-       new = (FcChar8 *) malloc (size);
-       if (!new)
+       full = (FcChar8 *) malloc (size);
+       if (!full)
            return 0;
-       FcMemAlloc (FC_MEM_STRING, size);
-       strcpy ((char *) new, (char *) home);
-       strcat ((char *) new, (char *) s + 1);
+       strcpy ((char *) full, (char *) home);
+       strcat ((char *) full, (char *) s + 1);
+       new = FcStrCanonFilename (full);
+       free (full);
     }
     else
-    {
-       int     size = strlen ((char *) s) + 1;
-       new = (FcChar8 *) malloc (size);
-       if (!new)
-           return 0;
-       FcMemAlloc (FC_MEM_STRING, size);
-       strcpy ((char *) new, (const char *) s);
-    }
+       new = FcStrCanonFilename (s);
     return new;
 }
 
@@ -834,6 +830,66 @@ FcStrBasename (const FcChar8 *file)
     return FcStrCopy (slash + 1);
 }
 
+FcChar8 *
+FcStrCanonFilename (const FcChar8 *s)
+{
+    FcChar8 *file;
+    FcChar8 *f;
+    const FcChar8 *slash;
+    int size;
+    
+    if (*s != '/')
+    {
+       FcChar8 *full;
+       
+       FcChar8 cwd[FC_MAX_FILE_LEN + 2];
+       if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL)
+           return NULL;
+       strcat ((char *) cwd, "/");
+       full = FcStrPlus (cwd, s);
+       file = FcStrCanonFilename (full);
+       FcStrFree (full);
+       return file;
+    }
+    size = strlen ((char *) s) + 1;
+    file = malloc (size);
+    if (!file)
+       return NULL;
+    FcMemAlloc (FC_MEM_STRING, size);
+    slash = NULL;
+    f = file;
+    for (;;) {
+       if (*s == '/' || *s == '\0')
+       {
+           if (slash)
+           {
+               switch (s - slash) {
+               case 2:
+                   if (!strncmp ((char *) slash, "/.", 2))
+                   {
+                       f -= 2; /* trim /. from file */
+                   }
+                   break;
+               case 3:
+                   if (!strncmp ((char *) slash, "/..", 3))
+                   {
+                       f -= 3; /* trim /.. from file */
+                       while (f > file) {
+                           if (*--f == '/')
+                               break;
+                       }
+                   }
+                   break;
+               }
+           }
+           slash = s;
+       }
+       if (!(*f++ = *s++))
+           break;
+    }
+    return file;
+}
+
 FcStrSet *
 FcStrSetCreate (void)
 {
@@ -994,3 +1050,4 @@ FcStrListDone (FcStrList *list)
     FcMemFree (FC_MEM_STRLIST, sizeof (FcStrList));
     free (list);
 }
+