summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2022-05-30 00:32:17 +0100
committerJohn-Mark Bell <jmb@netsurf-browser.org>2022-05-30 00:32:17 +0100
commitb3bef342bc585e9fd451775d6fc8287d98b98684 (patch)
treeec1e437e9fec16cbc447d644cd78765f9de63cba
parent769b9ee5c1a1a70a0a75a78269ccabb2b7591832 (diff)
downloadlibrufl-b3bef342bc585e9fd451775d6fc8287d98b98684.tar.gz
librufl-b3bef342bc585e9fd451775d6fc8287d98b98684.tar.bz2
Substitution table/direct: handle >255 fonts
The direct substitution table constructor failed to allocate sufficient space to store the table in the case where there are more than 255 fonts installed on the system.
-rw-r--r--src/rufl_substitution_table.c2
-rw-r--r--test/INDEX1
-rw-r--r--test/Makefile3
-rw-r--r--test/manyfonts.c100
4 files changed, 104 insertions, 2 deletions
diff --git a/src/rufl_substitution_table.c b/src/rufl_substitution_table.c
index a599930..f5de7d8 100644
--- a/src/rufl_substitution_table.c
+++ b/src/rufl_substitution_table.c
@@ -818,7 +818,7 @@ static rufl_code direct(uint64_t *table, size_t table_entries,
/* Allocate table */
//XXX: can we just rearrange the existing one in-place?
- subst_table->table = malloc(table_size);
+ subst_table->table = malloc(table_size * (subst_table->bits_per_entry >> 3));
if (!subst_table->table) {
free(subst_table);
return rufl_OUT_OF_MEMORY;
diff --git a/test/INDEX b/test/INDEX
index a1b324c..417b032 100644
--- a/test/INDEX
+++ b/test/INDEX
@@ -5,3 +5,4 @@ nofonts Ensure a lack of fonts "works"
ucsinit Ensure that UCS FM initialisation works
olducsinit Ensure that UCS FM (pre 3.64) initialisation works
oldfminit Ensure that non-UCS FM initialisation works oldfminit
+manyfonts Ensure that more than 256 fonts works
diff --git a/test/Makefile b/test/Makefile
index ec15598..451ea46 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -9,7 +9,8 @@ else
DIR_TEST_ITEMS := nofonts:nofonts.c;harness.c;mocks.c \
oldfminit:oldfminit.c;harness.c;mocks.c \
olducsinit:olducsinit.c;harness.c;mocks.c \
- ucsinit:ucsinit.c;harness.c;mocks.c
+ ucsinit:ucsinit.c;harness.c;mocks.c \
+ manyfonts:manyfonts.c;harness.c;mocks.c
endif
include $(NSBUILD)/Makefile.subdir
diff --git a/test/manyfonts.c b/test/manyfonts.c
new file mode 100644
index 0000000..bc4b01e
--- /dev/null
+++ b/test/manyfonts.c
@@ -0,0 +1,100 @@
+/*
+ * XXX: This test currently needs the following patch to be valid.
+ * We need a way of ensuring the library chooses the direct substitution
+ * table format (which basically means we need to flood a plane with glyphs)
+ *
+ * diff --git a/src/rufl_substitution_table.c b/src/rufl_substitution_table.c
+ * index f5de7d8..2b58b72 100644
+ * --- a/src/rufl_substitution_table.c
+ * +++ b/src/rufl_substitution_table.c
+ * @@ -1019,7 +1019,7 @@ static rufl_code create_substitution_table_for_plane(unsigned int plane)
+ * table_entries, blocks_used);
+ * chd_size = rufl_substitution_table_estimate_size_chd(
+ * table_entries, blocks_used);
+ * - if (direct_size <= chd_size) {
+ * + if (1 || direct_size <= chd_size) {
+ * result = direct(table, table_entries, blocks_used,
+ * block_histogram,
+ * &rufl_substitution_table[plane]);
+ */
+
+#include <ftw.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "rufl.h"
+
+#include "harness.h"
+#include "testutils.h"
+
+static char template[] = "/tmp/manyfontsXXXXXX";
+static const char *ptmp = NULL;
+
+static int ftw_cb(const char *path, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ (void) sb;
+ (void) typeflag;
+ (void) ftwbuf;
+
+ remove(path);
+
+ return 0;
+}
+
+static void cleanup(void)
+{
+ if (ptmp == NULL)
+ return;
+
+ nftw(ptmp, ftw_cb, FOPEN_MAX, FTW_DEPTH | FTW_MOUNT | FTW_PHYS);
+}
+
+int main(int argc, const char **argv)
+{
+ char *names[300];
+ int x;
+
+ UNUSED(argc);
+ UNUSED(argv);
+
+ ptmp = mkdtemp(template);
+ assert(NULL != ptmp);
+ atexit(cleanup);
+ chdir(ptmp);
+
+ rufl_test_harness_init(380, true, true);
+
+ for (x = 0; x < 300; x++) {
+ char buf[64];
+ sprintf(buf, "Font%03d", x);
+ names[x] = strdup(buf);
+ rufl_test_harness_register_font(names[x]);
+ }
+
+ assert(rufl_OK == rufl_init());
+ assert(NULL == rufl_fm_error);
+ assert(303 == rufl_family_list_entries);
+ assert(NULL != rufl_family_menu);
+
+ rufl_dump_state(true);
+
+ rufl_quit();
+
+ /* Reinit -- should load cache */
+ assert(rufl_OK == rufl_init());
+ assert(NULL == rufl_fm_error);
+ assert(303 == rufl_family_list_entries);
+ assert(NULL != rufl_family_menu);
+ /* Done for real this time */
+ rufl_quit();
+
+ for (x = 0; x < 300; x++) {
+ free(names[x]);
+ }
+
+ printf("PASS\n");
+
+ return 0;
+}