diff options
author | John-Mark Bell <jmb@netsurf-browser.org> | 2021-08-15 03:38:28 +0100 |
---|---|---|
committer | John-Mark Bell <jmb@netsurf-browser.org> | 2021-08-15 03:38:28 +0100 |
commit | d59f17a6fb3d4f20a931ab45bf60ff910685b241 (patch) | |
tree | ef70c90452c7b89e40a61e0847f4276918a1a6e6 | |
parent | 01da1538227f4d139c0665b730211c665c821625 (diff) | |
download | librufl-d59f17a6fb3d4f20a931ab45bf60ff910685b241.tar.gz librufl-d59f17a6fb3d4f20a931ab45bf60ff910685b241.tar.bz2 |
Ignore UCS fonts if using a non-UCS Font Manager
Attempting to use fonts constructed for the UCS Font Manager on
older systems generally results in bad outcomes up to, and
including, complete system freezes. As fixing the Font Manager
on these systems is impractical, simply ignore these fonts
completely when scanning for glyph coverage.
-rw-r--r-- | src/rufl_init.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/rufl_init.c b/src/rufl_init.c index 79433c3..6cf0be6 100644 --- a/src/rufl_init.c +++ b/src/rufl_init.c @@ -1028,10 +1028,33 @@ rufl_code rufl_init_scan_font_in_encoding(const char *font_name, if (code != rufl_OK) { LOG("rufl_init_read_encoding(\"%s\", ...): 0x%x", buf, code); + umap->encoding = NULL; xfont_lose_font(font); return code; } + /* Detect attempts to use UCS fonts with a non-UCS Font Manager. + * There is a bug in all known non-UCS Font Managers which is + * often triggered by scanning many fonts. The Font Manager will + * attempt to dereference a bogus pointer (at the start of + * getbbox_unscaled) and thus cause an abort in SVC mode. + * Fallout can be as (relatively) benign as the application + * crashing or escalate to an entire system freeze requiring + * a reset. As there are no "good" outcomes here, and we do + * not have a time machine to go back and fix long-ago released + * Font Managers, ensure we ignore UCS fonts here. */ + if ((uint32_t) umap->encoding > 256) { + static os_error err = { + error_FONT_TOO_MANY_CHUNKS, "Rejecting UCS font"}; + LOG("%s", "Rejecting UCS font"); + umap->encoding = NULL; + xfont_lose_font(font); + rufl_fm_error = &err; + return rufl_FONT_MANAGER_ERROR; + } + /* Eliminate all trace of our (ab)use of the encoding field */ + umap->encoding = NULL; + for (i = 0; i != umap->entries; i++) { u = umap->map[i].u; string[0] = umap->map[i].c; @@ -1102,9 +1125,11 @@ static rufl_code rufl_init_umap_cb(void *pw, uint32_t glyph_idx, uint32_t ucs4) umap->map[umap->entries].u = ucs4; umap->map[umap->entries].c = glyph_idx; umap->entries++; - if (umap->entries == 256) - result = rufl_IO_EOF; } + /* Stash the total number of encoding file entries so that + * rufl_init_scan_font_in_encoding can detect the presence of a + * UCS font on a non-UCS capable system. It will clean up for us. */ + umap->encoding = (void *) (((uint32_t) umap->encoding) + 1); return result; } |