diff --git a/src/fccache.c b/src/fccache.c index bec017e..7c3edc5 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -152,14 +152,25 @@ FcDirCacheBasenameMD5 (FcConfig *config, const FcChar8 *dir, FcChar8 cache_base[ { FcChar8 *new_dir; unsigned char hash[16]; - FcChar8 *hex_hash; + FcChar8 *hex_hash, *key = NULL; int cnt; struct MD5Context ctx; + const FcChar8 *salt; + salt = FcConfigMapSalt (config, dir); new_dir = FcConfigMapFontPath(config, dir); if (new_dir) dir = new_dir; + if (salt) + { + size_t dl = strlen ((const char *) dir); + size_t sl = strlen ((const char *) salt); + key = (FcChar8 *) malloc (dl + sl + 1); + memcpy (key, dir, dl); + memcpy (key + dl, salt, sl + 1); + dir = key; + } MD5Init (&ctx); MD5Update (&ctx, (const unsigned char *)dir, strlen ((const char *) dir)); @@ -167,6 +178,8 @@ FcDirCacheBasenameMD5 (FcConfig *config, const FcChar8 *dir, FcChar8 cache_base[ if (new_dir) FcStrFree(new_dir); + if (key) + FcStrFree (key); cache_base[0] = '/'; hex_hash = cache_base + 1; diff --git a/src/fccfg.c b/src/fccfg.c index 422608c..db93118 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -540,9 +540,10 @@ FcConfigGetConfigDirs (FcConfig *config) FcBool FcConfigAddFontDir (FcConfig *config, const FcChar8 *d, - const FcChar8 *m) + const FcChar8 *m, + const FcChar8 *salt) { - return FcStrSetAddFilenamePair (config->fontDirs, d, m); + return FcStrSetAddFilenamePairWithSalt (config->fontDirs, d, m, salt); } FcBool @@ -587,7 +588,7 @@ FcConfigMapFontPath(FcConfig *config, { FcStrList *list; FcChar8 *dir; - FcChar8 *map; + const FcChar8 *map; FcChar8 *retval; list = FcConfigGetFontDirs(config); @@ -599,7 +600,7 @@ FcConfigMapFontPath(FcConfig *config, FcStrListDone(list); if (!dir) return 0; - map = FcStrPairSecond(dir); + map = FcStrTripleSecond(dir); if (!map) return 0; retval = FcStrBuildFilename(map, path + strlen((char *) dir), NULL); @@ -615,6 +616,26 @@ FcConfigMapFontPath(FcConfig *config, return retval; } +const FcChar8 * +FcConfigMapSalt (FcConfig *config, + const FcChar8 *path) +{ + FcStrList *list; + FcChar8 *dir; + + list = FcConfigGetFontDirs (config); + if (!list) + return NULL; + while ((dir = FcStrListNext (list))) + if (FcConfigPathStartsWith (path, dir)) + break; + FcStrListDone (list); + if (!dir) + return NULL; + + return FcStrTripleThird (dir); +} + FcBool FcConfigAddCacheDir (FcConfig *config, const FcChar8 *d) diff --git a/src/fcint.h b/src/fcint.h index 5cfdcc3..7fad78f 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -660,7 +660,8 @@ FcConfigAddConfigDir (FcConfig *config, FcPrivate FcBool FcConfigAddFontDir (FcConfig *config, const FcChar8 *d, - const FcChar8 *m); + const FcChar8 *m, + const FcChar8 *salt); FcPrivate FcBool FcConfigResetFontDirs (FcConfig *config); @@ -669,6 +670,10 @@ FcPrivate FcChar8 * FcConfigMapFontPath(FcConfig *config, const FcChar8 *path); +FcPrivate const FcChar8 * +FcConfigMapSalt (FcConfig *config, + const FcChar8 *path); + FcPrivate FcBool FcConfigAddCacheDir (FcConfig *config, const FcChar8 *d); @@ -1245,13 +1250,16 @@ FcPrivate void FcStrSetSort (FcStrSet * set); FcPrivate FcBool -FcStrSetAddPair (FcStrSet *set, const FcChar8 *a, const FcChar8 *b); +FcStrSetAddTriple (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcChar8 *c); -FcPrivate FcChar8 * -FcStrPairSecond (FcChar8 *s); +FcPrivate const FcChar8 * +FcStrTripleSecond (FcChar8 *s); + +FcPrivate const FcChar8 * +FcStrTripleThird (FcChar8 *str); FcPrivate FcBool -FcStrSetAddFilenamePair (FcStrSet *strs, const FcChar8 *d, const FcChar8 *m); +FcStrSetAddFilenamePairWithSalt (FcStrSet *strs, const FcChar8 *d, const FcChar8 *m, const FcChar8 *salt); FcPrivate FcBool FcStrSetDeleteAll (FcStrSet *set); diff --git a/src/fcstr.c b/src/fcstr.c index 53cd1f7..2d3c510 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -37,11 +37,12 @@ FcStrCopy (const FcChar8 *s) } static FcChar8 * -FcStrMakePair (const FcChar8 *s1, const FcChar8 *s2) +FcStrMakeTriple (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *s3) { int s1l = s1 ? strlen ((char *) s1) : 0; int s2l = s2 ? strlen ((char *) s2) : 0; - int l = s1l + 1 + s2l + 1; + int s3l = s3 ? strlen ((char *) s3) : 0; + int l = s1l + 1 + s2l + 1 + s3l + 1; FcChar8 *s = malloc (l); if (!s) @@ -54,6 +55,10 @@ FcStrMakePair (const FcChar8 *s1, const FcChar8 *s2) memcpy (s + s1l + 1, s2, s2l + 1); else s[s1l + 1] = '\0'; + if (s3) + memcpy (s + s1l + 1 + s2l + 1, s3, s3l + 1); + else + s[s1l + 1 + s2l + 1] = '\0'; return s; } @@ -1255,9 +1260,9 @@ FcStrSetAdd (FcStrSet *set, const FcChar8 *s) } FcBool -FcStrSetAddPair (FcStrSet *set, const FcChar8 *a, const FcChar8 *b) +FcStrSetAddTriple (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcChar8 *c) { - FcChar8 *new = FcStrMakePair (a, b); + FcChar8 *new = FcStrMakeTriple (a, b, c); if (!new) return FcFalse; if (!_FcStrSetAppend (set, new)) @@ -1268,8 +1273,8 @@ FcStrSetAddPair (FcStrSet *set, const FcChar8 *a, const FcChar8 *b) return FcTrue; } -FcChar8 * -FcStrPairSecond (FcChar8 *str) +const FcChar8 * +FcStrTripleSecond (FcChar8 *str) { FcChar8 *second = str + strlen((char *) str) + 1; @@ -1278,6 +1283,17 @@ FcStrPairSecond (FcChar8 *str) return second; } +const FcChar8 * +FcStrTripleThird (FcChar8 *str) +{ + FcChar8 *second = str + strlen ((char *) str) + 1; + FcChar8 *third = second + strlen ((char *) second) + 1; + + if (*third == '\0') + return 0; + return third; +} + FcBool FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s) { @@ -1293,7 +1309,7 @@ FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s) } FcBool -FcStrSetAddFilenamePair (FcStrSet *set, const FcChar8 *a, const FcChar8 *b) +FcStrSetAddFilenamePairWithSalt (FcStrSet *set, const FcChar8 *a, const FcChar8 *b, const FcChar8 *salt) { FcChar8 *new_a = NULL; FcChar8 *new_b = NULL; @@ -1315,7 +1331,7 @@ FcStrSetAddFilenamePair (FcStrSet *set, const FcChar8 *a, const FcChar8 *b) return FcFalse; } } - ret = FcStrSetAddPair (set, new_a, new_b); + ret = FcStrSetAddTriple (set, new_a, new_b, salt); if (new_a) FcStrFree (new_a); if (new_b) diff --git a/src/fcxml.c b/src/fcxml.c index 955a2b0..88804d7 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -2057,7 +2057,7 @@ FcParseDescription (FcConfigParse *parse) static void FcParseRemapDir (FcConfigParse *parse) { - const FcChar8 *path, *attr, *data; + const FcChar8 *path, *attr, *data, *salt; FcChar8 *prefix = NULL; data = FcStrBufDoneStatic (&parse->pstack->str); @@ -2073,12 +2073,13 @@ FcParseRemapDir (FcConfigParse *parse) return; } attr = FcConfigGetAttribute (parse, "prefix"); + salt = FcConfigGetAttribute (parse, "salt"); prefix = _get_real_path_from_prefix (parse, data, attr); if (!prefix || prefix[0] == 0) FcConfigMessage (parse, FcSevereWarning, "empty font directory name for remap ignored"); else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ())) { - if (!FcConfigAddFontDir (parse->config, prefix, path)) + if (!FcConfigAddFontDir (parse->config, prefix, path, salt)) FcConfigMessage (parse, FcSevereError, "out of memory; cannot create remap data for %s as %s", prefix, path); } FcStrBufDestroy (&parse->pstack->str); @@ -2237,7 +2238,7 @@ FcParseUnary (FcConfigParse *parse, FcOp op) static void FcParseDir (FcConfigParse *parse) { - const FcChar8 *attr, *data; + const FcChar8 *attr, *data, *salt; FcChar8 *prefix = NULL; data = FcStrBufDoneStatic (&parse->pstack->str); @@ -2247,12 +2248,13 @@ FcParseDir (FcConfigParse *parse) return; } attr = FcConfigGetAttribute (parse, "prefix"); + salt = FcConfigGetAttribute (parse, "salt"); prefix = _get_real_path_from_prefix (parse, data, attr); if (!prefix || prefix[0] == 0) FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored"); else if (!parse->scanOnly && (!FcStrUsesHome (prefix) || FcConfigHome ())) { - if (!FcConfigAddFontDir (parse->config, prefix, NULL)) + if (!FcConfigAddFontDir (parse->config, prefix, NULL, salt)) FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", prefix); } FcStrBufDestroy (&parse->pstack->str); diff --git a/test/run-test.sh b/test/run-test.sh index 0183eaf..2bda9c2 100644 --- a/test/run-test.sh +++ b/test/run-test.sh @@ -172,6 +172,53 @@ if cmp flist1 flist2 > /dev/null ; then : ; else exit 1 fi rm -rf $TESTTMPDIR out1 out2 xxx flist1 flist2 bind-fonts.conf + +dotest "Different directory content between host and sandbox" +prep +cp $FONT1 $FONTDIR +$FCCACHE $FONTDIR +sleep 1 +ls -1 --color=no $CACHEDIR/*cache*> out1 +stat -c '%n %s %y %z' `cat out1` > stat1 +TESTTMPDIR=`mktemp -d /tmp/fontconfig.XXXXXXXX` +TESTTMP2DIR=`mktemp -d /tmp/fontconfig.XXXXXXXX` +cp $FONT2 $TESTTMP2DIR +sed "s!@FONTDIR@!$TESTTMPDIR/fonts$FONTDIR! +s!@REMAPDIR@!$TESTTMPDIR/fonts! +s!@CACHEDIR@!$TESTTMPDIR/cache.dir!" < $TESTDIR/fonts.conf.in > bind-fonts.conf +$BWRAP --bind / / --bind $CACHEDIR $TESTTMPDIR/cache.dir --bind $FONTDIR $TESTTMPDIR/fonts --bind $TESTTMP2DIR $FONTDIR --bind .. $TESTTMPDIR/build --dev-bind /dev /dev --setenv FONTCONFIG_FILE $TESTTMPDIR/build/test/bind-fonts.conf $TESTTMPDIR/build/fc-match/fc-match$EXEEXT -f "%{file}\n" ":foundry=Misc" > xxx +$BWRAP --bind / / --bind $CACHEDIR $TESTTMPDIR/cache.dir --bind $FONTDIR $TESTTMPDIR/fonts --bind $TESTTMP2DIR $FONTDIR --bind .. $TESTTMPDIR/build --dev-bind /dev /dev --setenv FONTCONFIG_FILE $TESTTMPDIR/build/test/bind-fonts.conf $TESTTMPDIR/build/test/test-bz106618$EXEEXT | sort > flist1 +$BWRAP --bind / / --bind $CACHEDIR $TESTTMPDIR/cache.dir --bind $FONTDIR $TESTTMPDIR/fonts --bind $TESTTMP2DIR $FONTDIR --bind .. $TESTTMPDIR/build --dev-bind /dev /dev find $TESTTMPDIR/fonts/ -type f -name '*.pcf' | sort > flist2 +ls -1 --color=no $CACHEDIR/*cache* > out2 +stat -c '%n %s %y %z' `cat out1` > stat2 +if cmp stat1 stat2 > /dev/null ; then : ; else + echo "*** Test failed: $TEST" + echo "cache was created/updated." + cat stat1 stat2 + exit 1 +fi +if grep -v -- "`cat out1`" out2 > /dev/null ; then : ; else + echo "*** Test failed: $TEST" + echo "cache wasn't created for dir inside sandbox." + cat out1 out2 + exit 1 +fi +if [ x`cat xxx` != "x$TESTTMPDIR/fonts/4x6.pcf" ]; then + echo "*** Test failed: $TEST" + echo "file property doesn't point to the new place: $TESTTMPDIR/fonts/4x6.pcf" + exit 1 +fi +if cmp flist1 flist2 > /dev/null ; then + echo "*** Test failed: $TEST" + echo "Missing fonts should be available on sandbox" + echo "Expected result:" + cat flist2 + echo "Actual result:" + cat flist1 + exit 1 +fi +rm -rf $TESTTMPDIR $TESTTMP2DIR out1 out2 xxx flist1 flist2 stat1 stat2 bind-fonts.conf + fi if [ "x$EXEEXT" = "x" ]; then