summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorent Rougon <f.rougon@free.fr>2017-06-06 23:32:28 +0200
committerAkira TAGOH <akira@tagoh.org>2017-06-09 14:35:43 +0900
commit4970c7e810fec29b5ad40a595850288f14f48e37 (patch)
treee8e4c2e4b1e3506669858d6514d636d06138dc10
parent02161ef2d6eda4e9c0ad068058d51a67a09af92f (diff)
Fix an off-by-one error in FcLangSetIndex()
This commit fixes a bug that can be reproduced like this: - remove all languages starting with 'a' in fc-lang/Makefile.am (in ORTH's definition); - rebuild fontconfig with this change (-> new fc-lang/fclang.h); - create an FcLangSet 'ls1' that contains at least the first language from fcLangCharSets (i.e., the first *remaining* in lexicographic order); let's assume it is "ba" for the sake of this description; - create an FcLangSet 'ls2' that only contains the language "aa" (any language starting with 'a' should work as well); - check the return value of FcLangSetContains(ls1, ls2); The expected return value is FcFalse, however it is FcTrue if you use the code before this commit. What happens is that FcLangSetIndex() returns 0, because this is the index of the first slot after the not-found language "aa" in fcLangCharSets (since we removed all languages starting with 'a'). However, this index happens to be non-negative, therefore FcLangSetContainsLang() mistakenly infers that the language "aa" was found in fcLangCharSets, and thus calls FcLangSetBitGet(ls1, 0), which returns FcTrue since we've put the first remaining language "ba" in the 'ls1' language set. The "return -low;" statement previously in FcLangSetIndex() was inconsistent with the final return statement. "return -(low+1);" fixes this inconsistency as well as the incorrect behavior described above.
-rw-r--r--src/fclang.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/fclang.c b/src/fclang.c
index b1fd1bca..19f3ddd4 100644
--- a/src/fclang.c
+++ b/src/fclang.c
@@ -505,6 +505,15 @@ bail0:
return 0;
}
+/* When the language isn't found, the return value r is such that:
+ * 1) r < 0
+ * 2) -r -1 is the index of the first language in fcLangCharSets that comes
+ * after the 'lang' argument in lexicographic order.
+ *
+ * The -1 is necessary to avoid problems with language id 0 (otherwise, we
+ * wouldn't be able to distinguish between “language found, id is 0” and
+ * “language not found, sorts right before the language with id 0”).
+ */
static int
FcLangSetIndex (const FcChar8 *lang)
{
@@ -529,7 +538,7 @@ FcLangSetIndex (const FcChar8 *lang)
high = fcLangCharSetRanges[firstChar - 'a'].end;
/* no matches */
if (low > high)
- return -low; /* next entry after where it would be */
+ return -(low+1); /* one past next entry after where it would be */
}
while (low <= high)