Fix set_fonts() in Xlib/xft and Cairo Graphics_Driver

src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx:
 - fix font_name_process() out of bounds memory access
 - unify/align font_name_process() code (see also Xlib/xft)
 - fix font name string allocation

src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
 - unify/align font_name_process() code (see also Cairo_Graphics)
 - fix font name string allocation

Todo: move common code to Fl_Graphics_Driver or another common file.
This commit is contained in:
Albrecht Schlosser 2023-01-13 22:39:23 +01:00
parent f3e21ddad2
commit a4fdf92d06
2 changed files with 26 additions and 20 deletions

View File

@ -1,7 +1,7 @@
// //
// Support for Cairo graphics for the Fast Light Tool Kit (FLTK). // Support for Cairo graphics for the Fast Light Tool Kit (FLTK).
// //
// Copyright 2021-2022 by Bill Spitzak and others. // Copyright 2021-2023 by Bill Spitzak and others.
// //
// This library is free software. Distribution and use rights are outlined in // This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this // the file "COPYING" which should have been included with this file. If this
@ -1012,14 +1012,17 @@ void Fl_Cairo_Graphics_Driver::init_built_in_fonts() {
} }
// FIXME: this (static) function should likely be in Fl_Graphics_Driver.
// The code is the same as in src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
static int font_name_process(const char *name, char &face) { static int font_name_process(const char *name, char &face) {
int l = strlen(name); int l = strlen(name);
face = ' '; face = ' ';
if (!memcmp(name + l - 8, " Regular", 8)) l -= 8; if (l > 8 && !memcmp(name + l - 8, " Regular", 8)) l -= 8;
else if (!memcmp(name + l - 6, " Plain", 6)) l -= 6; else if (l > 6 && !memcmp(name + l - 6, " Plain", 6)) l -= 6;
else if (!memcmp(name + l - 12, " Bold Italic", 12)) {l -= 12; face='P';} else if (l > 12 && !memcmp(name + l - 12, " Bold Italic", 12)) {l -= 12; face = 'P';}
else if (!memcmp(name + l - 7, " Italic", 7)) {l -= 7; face='I';} else if (l > 7 && !memcmp(name + l - 7, " Italic", 7)) {l -= 7; face = 'I';}
else if (!memcmp(name + l - 5, " Bold", 5)) {l -= 5; face='B';} else if (l > 5 && !memcmp(name + l - 5, " Bold", 5)) {l -= 5; face = 'B';}
return l; return l;
} }
@ -1047,14 +1050,14 @@ Fl_Font Fl_Cairo_Graphics_Driver::set_fonts(const char* /*pattern_name*/)
PangoFontFace **faces; PangoFontFace **faces;
int n_faces; int n_faces;
const char *fam_name = pango_font_family_get_name (families[fam]); const char *fam_name = pango_font_family_get_name (families[fam]);
int l = strlen(fam_name); int lfam = strlen(fam_name);
pango_font_family_list_faces(families[fam], &faces, &n_faces); pango_font_family_list_faces(families[fam], &faces, &n_faces);
for (int j = 0; j < n_faces; j++) { for (int j = 0; j < n_faces; j++) {
const char *p = pango_font_face_get_face_name(faces[j]); const char *p = pango_font_face_get_face_name(faces[j]);
// build the font's FLTK name // build the font's FLTK name
l += strlen(p) + 2; int lfont = lfam + strlen(p) + 2;
char *q = new char[l]; char *q = new char[lfont];
snprintf(q, l, "%s %s", fam_name, p); snprintf(q, lfont, "%s %s", fam_name, p);
Fl::set_font((Fl_Font)(count++ + FL_FREE_FONT), q); Fl::set_font((Fl_Font)(count++ + FL_FREE_FONT), q);
} }
/*g_*/free(faces); // glib source code shows that g_free is equivalent to free /*g_*/free(faces); // glib source code shows that g_free is equivalent to free

View File

@ -1,7 +1,7 @@
// //
// More font utilities for the Fast Light Tool Kit (FLTK). // More font utilities for the Fast Light Tool Kit (FLTK).
// //
// Copyright 1998-2018 by Bill Spitzak and others. // Copyright 1998-2023 by Bill Spitzak and others.
// //
// This library is free software. Distribution and use rights are outlined in // This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this // the file "COPYING" which should have been included with this file. If this
@ -1312,14 +1312,17 @@ int Fl_Xlib_Graphics_Driver::descent_unscaled() {
else return -1; else return -1;
} }
// FIXME: this (static) function should likely be in Fl_Graphics_Driver.
// The code is the same as in src/drivers/Cairo/Fl_Cairo_Graphics_Driver.cxx
static int font_name_process(const char *name, char &face) { static int font_name_process(const char *name, char &face) {
int l = strlen(name); int l = strlen(name);
face = ' '; face = ' ';
if (l > 8 && !memcmp(name + l - 8, " Regular", 8)) l -= 8; if (l > 8 && !memcmp(name + l - 8, " Regular", 8)) l -= 8;
else if (l > 6 && !memcmp(name + l - 6, " Plain", 6)) l -= 6; else if (l > 6 && !memcmp(name + l - 6, " Plain", 6)) l -= 6;
else if (l > 12 && !memcmp(name + l - 12, " Bold Italic", 12)) {l -= 12; face='P';} else if (l > 12 && !memcmp(name + l - 12, " Bold Italic", 12)) {l -= 12; face = 'P';}
else if (l > 7 && !memcmp(name + l - 7, " Italic", 7)) {l -= 7; face='I';} else if (l > 7 && !memcmp(name + l - 7, " Italic", 7)) {l -= 7; face = 'I';}
else if (l > 5 && !memcmp(name + l - 5, " Bold", 5)) {l -= 5; face='B';} else if (l > 5 && !memcmp(name + l - 5, " Bold", 5)) {l -= 5; face = 'B';}
return l; return l;
} }
@ -1345,14 +1348,14 @@ Fl_Font Fl_Xlib_Graphics_Driver::set_fonts(const char* pattern_name)
PangoFontFace **faces; PangoFontFace **faces;
int n_faces; int n_faces;
const char *fam_name = pango_font_family_get_name (families[fam]); const char *fam_name = pango_font_family_get_name (families[fam]);
int l = strlen(fam_name); int lfam = strlen(fam_name);
pango_font_family_list_faces(families[fam], &faces, &n_faces); pango_font_family_list_faces(families[fam], &faces, &n_faces);
for (int j = 0; j < n_faces; j++) { for (int j = 0; j < n_faces; j++) {
const char *p = pango_font_face_get_face_name(faces[j]); const char *p = pango_font_face_get_face_name(faces[j]);
// build the font's FLTK name // build the font's FLTK name
l += strlen(p) + 2; int lfont = lfam + strlen(p) + 2;
char *q = new char[l]; char *q = new char[lfont];
snprintf(q, l, "%s %s", fam_name, p); snprintf(q, lfont, "%s %s", fam_name, p);
Fl::set_font((Fl_Font)(count++ + FL_FREE_FONT), q); Fl::set_font((Fl_Font)(count++ + FL_FREE_FONT), q);
} }
/*g_*/free(faces); // glib source code shows that g_free is equivalent to free /*g_*/free(faces); // glib source code shows that g_free is equivalent to free