ghostty-org/ghostty

hasLang misinterprets FcLangSetHasLang's FcLangResult as FcBool

Summary

  • ContextLangSet.hasLang() is a wrapper around fontconfig’s FcLangSetHasLang API, used to check if a font supports a specific language (e.g., to determine if a font is an emoji font via the “und-zsye” language tag).

  • BughasLang() incorrectly compares the return value of FcLangSetHasLang (which returns FcLangResult) to FcTrue (a boolean constant).

  • Actual vs. expectedFcLangSetHasLang returns a three-value enum (FcLangResult) indicating the quality of language match, but the code treats it as a boolean by comparing to FcTrue. This causes hasLang() to return true for partial matches (same language, different territory) when it should only return true for exact matches.

  • Impact: Fonts may be incorrectly identified as supporting a language when they only support a related language variant, potentially causing incorrect font selection in the emoji presentation detection logic.

Code with bug

pub fn hasLang(self: *const LangSet, lang: [:0]

Logical proof

FcLangResult FcLangSetHasLang(
    const FcLangSet *_ls_,
    const FcChar8   *_lang_

  • Return values: FcLangEqual (0), FcLangDifferentTerritory (1), FcLangDifferentLang (2)

  • Current code compares the enum result to FcTrue (boolean 1), yielding:

    • FcLangEqual (0) == 1 → false (exact match incorrectly returns false)

    • FcLangDifferentTerritory (1) == 1 → true (partial match incorrectly returns true)

    • FcLangDifferentLang (2) == 1 → false (mismatch correctly returns false) This demonstrates inverted behavior for exact matches and false positives for partial matches.

Recommended fix

pub fn hasLang(self: *const LangSet, lang: [:0]