mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-21 16:05:02 +02:00
Ignore invalid font features when parsing config
This commit is contained in:
@@ -410,6 +410,14 @@ def handle_symbol_map(key, val, ans):
|
|||||||
ans['symbol_map'].update(parse_symbol_map(val))
|
ans['symbol_map'].update(parse_symbol_map(val))
|
||||||
|
|
||||||
|
|
||||||
|
class FontFeature(str):
|
||||||
|
|
||||||
|
def __new__(cls, name, parsed):
|
||||||
|
ans = str.__new__(cls, name)
|
||||||
|
ans.parsed = parsed
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
@special_handler
|
@special_handler
|
||||||
def handle_font_features(key, val, ans):
|
def handle_font_features(key, val, ans):
|
||||||
if val != 'none':
|
if val != 'none':
|
||||||
@@ -417,7 +425,16 @@ def handle_font_features(key, val, ans):
|
|||||||
if len(parts) < 2:
|
if len(parts) < 2:
|
||||||
log_error("Ignoring invalid font_features {}".format(val))
|
log_error("Ignoring invalid font_features {}".format(val))
|
||||||
else:
|
else:
|
||||||
ans['font_features'][parts[0]] = parts[1:]
|
features = []
|
||||||
|
for feat in parts[1:]:
|
||||||
|
try:
|
||||||
|
parsed = defines.parse_font_feature(feat)
|
||||||
|
except ValueError:
|
||||||
|
log_error('Ignoring invalid font feature: {}'.format(feat))
|
||||||
|
else:
|
||||||
|
features.append(FontFeature(feat, parsed))
|
||||||
|
if features:
|
||||||
|
ans['font_features'][parts[0]] = tuple(features)
|
||||||
|
|
||||||
|
|
||||||
@special_handler
|
@special_handler
|
||||||
|
|||||||
@@ -355,17 +355,17 @@ init_font(Font *f, PyObject *face, bool bold, bool italic, bool emoji_presentati
|
|||||||
const char *psname = postscript_name_for_face(face);
|
const char *psname = postscript_name_for_face(face);
|
||||||
if (font_feature_settings != NULL){
|
if (font_feature_settings != NULL){
|
||||||
PyObject* o = PyDict_GetItemString(font_feature_settings, psname);
|
PyObject* o = PyDict_GetItemString(font_feature_settings, psname);
|
||||||
if (o != NULL) {
|
if (o != NULL && PyTuple_Check(o)) {
|
||||||
Py_ssize_t len = PySequence_Size(o);
|
Py_ssize_t len = PyTuple_GET_SIZE(o);
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
f->num_ffs_hb_features = len + 1;
|
f->num_ffs_hb_features = len + 1;
|
||||||
f->ffs_hb_features = calloc(f->num_ffs_hb_features, sizeof(hb_feature_t));
|
f->ffs_hb_features = calloc(f->num_ffs_hb_features, sizeof(hb_feature_t));
|
||||||
if (!f->ffs_hb_features) return false;
|
if (!f->ffs_hb_features) return false;
|
||||||
for (Py_ssize_t i = 0; i < len; i++) {
|
for (Py_ssize_t i = 0; i < len; i++) {
|
||||||
PyObject* item = PySequence_GetItem(o, i);
|
PyObject* parsed = PyObject_GetAttrString(PyTuple_GET_ITEM(o, i), "parsed");
|
||||||
if (!PyUnicode_Check(item)) fatal("A font feature is not a unicode string");
|
if (parsed) {
|
||||||
if (!hb_feature_from_string(PyUnicode_AsUTF8(item), -1, &f->ffs_hb_features[i])) {
|
memcpy(f->ffs_hb_features + i, PyBytes_AS_STRING(parsed), sizeof(hb_feature_t));
|
||||||
fatal("Invalid font feature: %s", PyUnicode_AsUTF8(item));
|
Py_DECREF(parsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(f->ffs_hb_features + len, &hb_features[CALT_FEATURE], sizeof(hb_feature_t));
|
memcpy(f->ffs_hb_features + len, &hb_features[CALT_FEATURE], sizeof(hb_feature_t));
|
||||||
@@ -1455,9 +1455,26 @@ free_font_data(PyObject *self UNUSED, PyObject *args UNUSED) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
parse_font_feature(PyObject *self UNUSED, PyObject *feature) {
|
||||||
|
if (!PyUnicode_Check(feature)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "feature must be a unicode object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *ans = PyBytes_FromStringAndSize(NULL, sizeof(hb_feature_t));
|
||||||
|
if (!ans) return NULL;
|
||||||
|
if (!hb_feature_from_string(PyUnicode_AsUTF8(feature), -1, (hb_feature_t*)PyBytes_AS_STRING(ans))) {
|
||||||
|
Py_CLEAR(ans);
|
||||||
|
PyErr_Format(PyExc_ValueError, "%U is not a valid font feature", feature);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
METHODB(set_font_data, METH_VARARGS),
|
METHODB(set_font_data, METH_VARARGS),
|
||||||
METHODB(free_font_data, METH_NOARGS),
|
METHODB(free_font_data, METH_NOARGS),
|
||||||
|
METHODB(parse_font_feature, METH_O),
|
||||||
METHODB(create_test_font_group, METH_VARARGS),
|
METHODB(create_test_font_group, METH_VARARGS),
|
||||||
METHODB(sprite_map_set_layout, METH_VARARGS),
|
METHODB(sprite_map_set_layout, METH_VARARGS),
|
||||||
METHODB(test_sprite_position_for, METH_VARARGS),
|
METHODB(test_sprite_position_for, METH_VARARGS),
|
||||||
|
|||||||
Reference in New Issue
Block a user