summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2021-08-15 03:38:28 +0100
committerJohn-Mark Bell <jmb@netsurf-browser.org>2021-08-15 03:38:28 +0100
commitd59f17a6fb3d4f20a931ab45bf60ff910685b241 (patch)
treeef70c90452c7b89e40a61e0847f4276918a1a6e6
parent01da1538227f4d139c0665b730211c665c821625 (diff)
downloadlibrufl-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.c29
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;
}