summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2019-01-31 10:17:47 +0000
committerAkira TAGOH <akira@tagoh.org>2019-04-03 12:02:09 +0000
commit2e8ce63514b06590d36d9bf5c332ff83fb72791a (patch)
tree6000f6e9017e547e86accde25bc68069f1a7bfd8
parentdef1d00036a4e828382027292a167203c6c7a0b4 (diff)
Add salt attribute to dir and remap-dir elements
'salt' attribute affects a cache filename to generate different name from directory name. This is useful when sharing caches with host on sandbox and/or give a filename differently: <dir salt="randomdata">/usr/share/fonts</dir> <remap-dir as-path="/usr/share/fonts" salt="salt for /usr/share/fonts on host">/run/host/fonts</remap-dir> Applications can read caches as-is for fonts on /run/host/fonts where is mounted from host. and write a cache for their own fonts on /usr/share/fonts with different name.
-rw-r--r--src/fccache.c15
-rw-r--r--src/fccfg.c29
-rw-r--r--src/fcint.h18
-rw-r--r--src/fcstr.c32
-rw-r--r--src/fcxml.c10
-rw-r--r--test/run-test.sh47
6 files changed, 129 insertions, 22 deletions
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</dir><dir salt="'"'"salt-to-make-different"'"'">$FONTDIR!
+s!@REMAPDIR@!<remap-dir as-path="'"'"$FONTDIR"'"'">$TESTTMPDIR/fonts</remap-dir>!
+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