From 00dc8f0e230d61e5085f4c7320f2e23a1dd48787 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 22 Apr 2024 19:17:28 +0530 Subject: [PATCH] Ensure fontconfig pattern dict has all keys with default values --- kitty/fontconfig.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/kitty/fontconfig.c b/kitty/fontconfig.c index a9b027181..bea6ede52 100644 --- a/kitty/fontconfig.c +++ b/kitty/fontconfig.c @@ -147,39 +147,39 @@ pyspacing(int val) { #undef S } +static PyObject* +increment_and_return(PyObject *x) { if (x) Py_INCREF(x); return x; } static PyObject* pattern_as_dict(FcPattern *pat) { - PyObject *ans = Py_BuildValue("{ss}", "descriptor_type", "fontconfig"), *p = NULL, *list = NULL; + RAII_PyObject(ans, Py_BuildValue("{ss}", "descriptor_type", "fontconfig")); if (ans == NULL) return NULL; #define PS(x) PyUnicode_Decode((const char*)x, strlen((const char*)x), "UTF-8", "replace") -#define G(type, get, which, conv, name) { \ +#define G(type, get, which, conv, name, default) { \ type out; \ if (get(pat, which, 0, &out) == FcResultMatch) { \ - p = conv(out); if (p == NULL) goto exit; \ - if (PyDict_SetItemString(ans, #name, p) != 0) goto exit; \ - Py_CLEAR(p); \ - }} + RAII_PyObject(p, conv(out)); \ + if (!p || PyDict_SetItemString(ans, #name, p) != 0) return NULL; \ + } else { RAII_PyObject(d, default); if (!d || PyDict_SetItemString(ans, #name, d) != 0) return NULL; } \ +} #define L(type, get, which, conv, name) { \ type out; int n = 0; \ - list = PyList_New(0); \ - if (!list) goto exit; \ + RAII_PyObject(list, PyList_New(0)); \ + if (!list) return NULL; \ while (get(pat, which, n++, &out) == FcResultMatch) { \ - p = conv(out); if (p == NULL) goto exit; \ - if (PyList_Append(list, p) != 0) goto exit; \ - Py_CLEAR(p); \ + RAII_PyObject(p, conv(out)); \ + if (!p || PyList_Append(list, p) != 0) return NULL; \ } \ - if (PyDict_SetItemString(ans, #name, list) != 0) goto exit; \ - Py_CLEAR(list); \ + if (PyDict_SetItemString(ans, #name, list) != 0) return NULL; \ } -#define S(which, key) G(FcChar8*, FcPatternGetString, which, PS, key) +#define S(which, key) G(FcChar8*, FcPatternGetString, which, PS, key, PyUnicode_FromString("")) #define LS(which, key) L(FcChar8*, FcPatternGetString, which, PS, key) -#define I(which, key) G(int, FcPatternGetInteger, which, PyLong_FromLong, key) -#define B(which, key) G(int, FcPatternGetBool, which, pybool, key) -#define E(which, key, conv) G(int, FcPatternGetInteger, which, conv, key) +#define I(which, key) G(int, FcPatternGetInteger, which, PyLong_FromLong, key, PyLong_FromUnsignedLong(0)) +#define B(which, key) G(int, FcPatternGetBool, which, pybool, key, increment_and_return(Py_False)) +#define E(which, key, conv) G(int, FcPatternGetInteger, which, conv, key, PyLong_FromUnsignedLong(0)) S(FC_FILE, path); S(FC_FAMILY, family); S(FC_STYLE, style); @@ -199,11 +199,8 @@ pattern_as_dict(FcPattern *pat) { B(FC_OUTLINE, outline); B(FC_COLOR, color); E(FC_SPACING, spacing, pyspacing); -exit: - if (PyErr_Occurred()) Py_CLEAR(ans); - Py_CLEAR(p); - Py_CLEAR(list); + Py_INCREF(ans); return ans; #undef PS #undef S