CMakeLists.txt | 23 -- appveyor.yml | 7 configure.ac | 2 m4/ax_check_link_flag.m4 | 74 ++++++++ src/Makefile.am | 15 + src/gen-def.py | 2 src/hb-directwrite.cc | 19 -- src/hb-ot-glyf-table.hh | 9 - src/hb-ot-hdmx-table.hh | 30 ++- src/hb-ot-hmtx-table.hh | 13 + src/hb-subset-glyf.cc | 9 - src/hb-subset.cc | 1 test/api/Makefile.am | 1 test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 |binary test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 |binary test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a |binary test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 |binary test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 |binary test/api/test-subset-hdmx.c | 23 ++ test/api/test-subset-hmtx.c | 23 ++ test/api/test-subset.c | 85 ++++++++++ test/fuzzing/CMakeLists.txt | 25 ++ test/fuzzing/Makefile.am | 35 +++- test/fuzzing/hb-subset-fuzzer.cc | 39 ++++ test/fuzzing/run-fuzzer-tests.py | 32 --- test/fuzzing/run-shape-fuzzer-tests.py | 34 ++++ test/fuzzing/run-subset-fuzzer-tests.py | 35 ++++ 27 files changed, 441 insertions(+), 95 deletions(-)
New commits: commit 3f55e0e74680c246819233a7250df612821698d7 Author: Garret Rieger <[email protected]> Date: Tue Mar 20 17:36:52 2018 -0700 [subset] Check for the Null table and not nullptr to detect failure to find a table in glyf accelerator. diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 11c3eaac..79467061 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -236,9 +236,9 @@ struct glyf hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head)); const head *head_table = Sanitizer<head>::lock_instance (head_blob); - if (!head_table || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) { - /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + /* head table is not present, or in an unknown format. Leave num_glyphs=0, that takes care of disabling us. */ hb_blob_destroy (head_blob); return; } @@ -268,7 +268,7 @@ struct glyf inline bool get_composite (hb_codepoint_t glyph, CompositeGlyphHeader::Iterator *composite /* OUT */) const { - if (!this->glyf_table || !num_glyphs) + if (this->glyf_table == &Null(glyf) || !num_glyphs) return false; unsigned int start_offset, end_offset; commit 45def99eae81e470be3c38d2962aafaaa85500b9 Author: Garret Rieger <[email protected]> Date: Tue Mar 20 17:28:47 2018 -0700 [subset] Fix to debug message. diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index 4d111008..1bbcbdcd 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -45,7 +45,7 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, hb_codepoint_t next_glyph = glyph_ids[i]; if (!instruction_ranges->resize (instruction_ranges->len + 2)) { - DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges.", next_glyph); + DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges."); return false; } unsigned int *instruction_start = &(*instruction_ranges)[instruction_ranges->len - 2]; commit 139661404006b8be039436a81cb6b1a73ec44042 Author: Garret Rieger <[email protected]> Date: Tue Mar 20 16:55:42 2018 -0700 [subset] don't use pointers returned from push after array has resized in hb-subset-glyf.cc diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index 0b84c856..4d111008 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -43,9 +43,14 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, for (unsigned int i = 0; i < glyph_ids.len; i++) { hb_codepoint_t next_glyph = glyph_ids[i]; - unsigned int *instruction_start = instruction_ranges->push(); - unsigned int *instruction_end = instruction_ranges->push(); + if (!instruction_ranges->resize (instruction_ranges->len + 2)) + { + DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges.", next_glyph); + return false; + } + unsigned int *instruction_start = &(*instruction_ranges)[instruction_ranges->len - 2]; *instruction_start = 0; + unsigned int *instruction_end = &(*instruction_ranges)[instruction_ranges->len - 1]; *instruction_end = 0; unsigned int start_offset, end_offset; diff --git a/test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 b/test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 new file mode 100644 index 00000000..00be056e Binary files /dev/null and b/test/api/fonts/crash-b577db318b30f2851828a4c9ef97cb30678b1b54 differ commit 3531efdb4c641ef543ea0686fef9289307d52096 Author: Garret Rieger <[email protected]> Date: Tue Mar 20 16:31:21 2018 -0700 [subset] Fixed out of bounds read when subsetting hdmx. diff --git a/src/hb-ot-hdmx-table.hh b/src/hb-ot-hdmx-table.hh index f08fe39d..8df99576 100644 --- a/src/hb-ot-hdmx-table.hh +++ b/src/hb-ot-hdmx-table.hh @@ -43,12 +43,15 @@ struct DeviceRecord struct SubsetView { const DeviceRecord *source_device_record; + unsigned int size_device_record; hb_subset_plan_t *subset_plan; inline void init(const DeviceRecord *source_device_record, + unsigned int size_device_record, hb_subset_plan_t *subset_plan) { this->source_device_record = source_device_record; + this->size_device_record = size_device_record; this->subset_plan = subset_plan; } @@ -57,11 +60,17 @@ struct DeviceRecord return this->subset_plan->gids_to_retain_sorted.len; } - inline const HBUINT8& operator [] (unsigned int i) const + inline const HBUINT8* operator [] (unsigned int i) const { - if (unlikely (i >= len())) return Null(HBUINT8); + if (unlikely (i >= len())) return nullptr; hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; - return this->source_device_record->widths[gid]; + + const HBUINT8* width = &(this->source_device_record->widths[gid]); + + if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record) + return width; + else + return nullptr; } }; @@ -85,7 +94,15 @@ struct DeviceRecord this->max_width.set (subset_view.source_device_record->max_width); for (unsigned int i = 0; i < subset_view.len(); i++) - widths[i].set (subset_view[i]); + { + const HBUINT8 *width = subset_view[i]; + if (!width) + { + DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i); + return_trace (false); + } + widths[i].set (*width); + } return_trace (true); } @@ -133,9 +150,10 @@ struct hdmx for (unsigned int i = 0; i < source_hdmx->num_records; i++) { DeviceRecord::SubsetView subset_view; - subset_view.init (&(*source_hdmx)[i], plan); + subset_view.init (&(*source_hdmx)[i], source_hdmx->size_device_record, plan); - c->start_embed<DeviceRecord> ()->serialize (c, subset_view); + if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view)) + return_trace (false); } return_trace (true); diff --git a/test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a b/test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a new file mode 100644 index 00000000..1af243eb Binary files /dev/null and b/test/api/fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a differ diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c index 609ee061..dd20b2a2 100644 --- a/test/api/test-subset-hdmx.c +++ b/test/api/test-subset-hdmx.c @@ -51,6 +51,28 @@ test_subset_hdmx_simple_subset (void) } static void +test_subset_hdmx_invalid (void) +{ + hb_face_t *face = hb_subset_test_open_font("fonts/crash-ccc61c92d589f895174cdef6ff2e3b20e9999a1a"); + + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t *codepoints = hb_subset_input_unicode_set (input); + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + + hb_subset_profile_t *profile = hb_subset_profile_create(); + hb_face_t *subset = hb_subset (face, profile, input); + g_assert (subset); + g_assert (subset == hb_face_get_empty ()); + + hb_subset_input_destroy (input); + hb_subset_profile_destroy (profile); + hb_face_destroy (subset); + hb_face_destroy (face); +} + +static void test_subset_hdmx_noop (void) { hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf"); @@ -75,6 +97,7 @@ main (int argc, char **argv) hb_test_init (&argc, &argv); hb_test_add (test_subset_hdmx_simple_subset); + hb_test_add (test_subset_hdmx_invalid); hb_test_add (test_subset_hdmx_noop); return hb_test_run(); commit e597436b994c0a553e85e4c2dbd74aa037e69b60 Author: Garret Rieger <[email protected]> Date: Tue Mar 20 13:00:49 2018 -0700 [subset] Disable glyf accelerator_t methods if it didn't successfully init. diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index d62f24bd..11c3eaac 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -232,9 +232,11 @@ struct glyf { inline void init (hb_face_t *face) { + memset (this, 0, sizeof (accelerator_t)); + hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head)); const head *head_table = Sanitizer<head>::lock_instance (head_blob); - if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + if (!head_table || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) { /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ hb_blob_destroy (head_blob); @@ -266,6 +268,9 @@ struct glyf inline bool get_composite (hb_codepoint_t glyph, CompositeGlyphHeader::Iterator *composite /* OUT */) const { + if (!this->glyf_table || !num_glyphs) + return false; + unsigned int start_offset, end_offset; if (!get_offsets (glyph, &start_offset, &end_offset)) return false; /* glyph not found */ diff --git a/test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 b/test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 new file mode 100644 index 00000000..b6b47ffe Binary files /dev/null and b/test/api/fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249 differ diff --git a/test/api/test-subset.c b/test/api/test-subset.c index 6f71e04d..6bf5c066 100644 --- a/test/api/test-subset.c +++ b/test/api/test-subset.c @@ -51,12 +51,35 @@ test_subset_32_tables (void) hb_face_destroy (face); } +static void +test_subset_crash (void) +{ + hb_face_t *face = hb_subset_test_open_font("fonts/crash-4b60576767ee4d9fe1cc10959d89baf73d4e8249"); + + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t *codepoints = hb_subset_input_unicode_set (input); + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + + hb_subset_profile_t *profile = hb_subset_profile_create(); + hb_face_t *subset = hb_subset (face, profile, input); + g_assert (subset); + g_assert (subset == hb_face_get_empty ()); + + hb_subset_input_destroy (input); + hb_subset_profile_destroy (profile); + hb_face_destroy (subset); + hb_face_destroy (face); +} + int main (int argc, char **argv) { hb_test_init (&argc, &argv); hb_test_add (test_subset_32_tables); + hb_test_add (test_subset_crash); return hb_test_run(); } commit 7251181b56af564e2a9444f002f8ac03f98c7ee3 Author: Garret Rieger <[email protected]> Date: Tue Mar 20 11:21:06 2018 -0700 [subset] Fix infinite loop in there are more then 32 tables. diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 30cba3fc..75121c56 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -359,6 +359,7 @@ hb_subset (hb_face_t *source, continue; } success = success && _subset_table (plan, tag); + offset += count; } } while (count == ARRAY_LENGTH (table_tags)); diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 54e367fa..0e63b1d7 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -31,6 +31,7 @@ TEST_PROGS = \ test-object \ test-set \ test-shape \ + test-subset \ test-subset-cmap \ test-subset-glyf \ test-subset-hdmx \ diff --git a/test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 b/test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 new file mode 100644 index 00000000..0bb0f0f0 Binary files /dev/null and b/test/api/fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653 differ diff --git a/test/api/test-subset.c b/test/api/test-subset.c new file mode 100644 index 00000000..6f71e04d --- /dev/null +++ b/test/api/test-subset.c @@ -0,0 +1,62 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "hb-test.h" +#include "hb-subset-test.h" + +/* Unit tests for hb-subset-glyf.h */ + +static void +test_subset_32_tables (void) +{ + hb_face_t *face = hb_subset_test_open_font("fonts/oom-6ef8c96d3710262511bcc730dce9c00e722cb653"); + + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t *codepoints = hb_subset_input_unicode_set (input); + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + + hb_subset_profile_t *profile = hb_subset_profile_create(); + hb_face_t *subset = hb_subset (face, profile, input); + g_assert (subset); + g_assert (subset != hb_face_get_empty ()); + + hb_subset_input_destroy (input); + hb_subset_profile_destroy (profile); + hb_face_destroy (subset); + hb_face_destroy (face); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_subset_32_tables); + + return hb_test_run(); +} commit 1a94804d35d533d39849d21a177039c4cbfade98 Author: Garret Rieger <[email protected]> Date: Mon Mar 19 18:39:22 2018 -0700 [subset] Add a fix for segfault in hmtx/vmtx subsetting code. diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index bff792a6..2af9a5cc 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -118,6 +118,8 @@ struct hmtxvmtx LongMetric * old_metrics = (LongMetric *) source_table; FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances); char * dest_pos = (char *) dest; + + bool failed = false; for (unsigned int i = 0; i < gids.len; i++) { /* the last metric or the one for gids[i] */ @@ -138,7 +140,14 @@ struct hmtxvmtx } else { - FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); + if (gids[i] >= _mtx.num_metrics) + { + DEBUG_MSG(SUBSET, nullptr, "gid %d is >= number of source metrics %d", + gids[i], _mtx.num_metrics); + failed = true; + break; + } + FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); if (i < num_advances) { /* dest needs a full LongMetric */ @@ -157,7 +166,7 @@ struct hmtxvmtx _mtx.fini (); // Amend header num hmetrics - if (unlikely (!subset_update_header (plan, num_advances))) + if (failed || unlikely (!subset_update_header (plan, num_advances))) { free (dest); return false; diff --git a/test/api/test-subset-hmtx.c b/test/api/test-subset-hmtx.c index cb224972..0ed62562 100644 --- a/test/api/test-subset-hmtx.c +++ b/test/api/test-subset-hmtx.c @@ -163,7 +163,8 @@ test_subset_invalid_hmtx (void) hb_subset_profile_t *profile = hb_subset_profile_create(); hb_face_t *subset = hb_subset (face, profile, input); - g_assert (!subset); + g_assert (subset); + g_assert (subset == hb_face_get_empty ()); hb_subset_input_destroy (input); hb_subset_profile_destroy (profile); commit 31281d6a17a03a124456a4cab54e31b248b41267 Author: Garret Rieger <[email protected]> Date: Mon Mar 19 17:47:57 2018 -0700 [subset] Add a test demonstrating a seg fault while subsetting hmtx. diff --git a/test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 b/test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 new file mode 100644 index 00000000..890c4498 Binary files /dev/null and b/test/api/fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480 differ diff --git a/test/api/test-subset-hmtx.c b/test/api/test-subset-hmtx.c index fc57718a..cb224972 100644 --- a/test/api/test-subset-hmtx.c +++ b/test/api/test-subset-hmtx.c @@ -150,6 +150,27 @@ test_subset_hmtx_noop (void) hb_face_destroy (face_abc); } +static void +test_subset_invalid_hmtx (void) +{ + hb_face_t *face = hb_subset_test_open_font("fonts/crash-e4e0bb1458a91b692eba492c907ae1f94e635480"); + + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t *codepoints = hb_subset_input_unicode_set (input); + hb_set_add (codepoints, 'a'); + hb_set_add (codepoints, 'b'); + hb_set_add (codepoints, 'c'); + + hb_subset_profile_t *profile = hb_subset_profile_create(); + hb_face_t *subset = hb_subset (face, profile, input); + g_assert (!subset); + + hb_subset_input_destroy (input); + hb_subset_profile_destroy (profile); + hb_face_destroy (subset); + hb_face_destroy (face); +} + int main (int argc, char **argv) { @@ -160,6 +181,7 @@ main (int argc, char **argv) hb_test_add (test_subset_hmtx_keep_num_metrics); hb_test_add (test_subset_hmtx_decrease_num_metrics); hb_test_add (test_subset_hmtx_noop); + hb_test_add (test_subset_invalid_hmtx); return hb_test_run(); } commit b5c7d6cffc2098dafa06822b28a5fd4f6218b60c Author: Garret Rieger <[email protected]> Date: Fri Mar 16 10:20:21 2018 -0700 [subset] Restore subset to hb-subset-fuzzer. diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index dc9f9016..a57f41dc 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -55,7 +55,7 @@ hb_subset_fuzzer_SOURCES = \ main.cc \ $(NULL) hb_subset_fuzzer_LDADD = \ - $(top_builddir)/src/libharfbuzz-fuzzing.la \ + $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \ $(NULL) hb_subset_fuzzer_CPPFLAGS = \ $(AM_CPPFLAGS) \ diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc index c59a8e28..1e26d26a 100644 --- a/test/fuzzing/hb-subset-fuzzer.cc +++ b/test/fuzzing/hb-subset-fuzzer.cc @@ -9,7 +9,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { printf ("hb-subset-fuzzer: input size = %zu\n", size); - /* hb_blob_t *blob = hb_blob_create ((const char *)data, size, HB_MEMORY_MODE_READONLY, NULL, NULL); hb_face_t *face = hb_face_create (blob, 0); @@ -35,7 +34,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) hb_subset_profile_destroy (profile); hb_face_destroy (face); hb_blob_destroy (blob); - */ return 0; } commit 957e7756634a4fdf1654041e20e883cf964ecac9 Author: Ebrahim Byagowi <[email protected]> Date: Mon Mar 19 12:19:42 2018 +0330 [dwrite] Use new again and enable the build on msys2 bots (#890) diff --git a/appveyor.yml b/appveyor.yml index 5971337c..b6857206 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,11 +20,11 @@ environment: - compiler: msys2 - MINGW_PREFIX: /c/msys2/mingw64/ + MINGW_PREFIX: /mingw64 MINGW_CHOST: x86_64-w64-mingw32 MSYS2_ARCH: x86_64 - compiler: msys2 - MINGW_PREFIX: /c/msys2/mingw32/ + MINGW_PREFIX: /mingw32 MINGW_CHOST: i686-w64-mingw32 MSYS2_ARCH: i686 @@ -44,7 +44,8 @@ build_script: - 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" ctest --output-on-failure -C %configuration%' - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-$MSYS2_ARCH-{freetype,cairo,icu,gettext,gobject-introspection,gcc,gcc-libs,glib2,graphite2,pkg-config,python2}"' - - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make; make check || .ci/fail.sh"' + - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-headers/include/dwrite_1.h?format=raw > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"' + - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make; make check || .ci/fail.sh"' cache: - c:\tools\vcpkg\installed\ diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index 40e9e39b..0d3b1c2e 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -48,7 +48,7 @@ class DWriteFontFileLoader : public IDWriteFontFileLoader private: IDWriteFontFileStream *mFontFileStream; public: - void init (IDWriteFontFileStream *fontFileStream) + DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) { mFontFileStream = fontFileStream; } @@ -74,7 +74,7 @@ private: uint8_t *mData; uint32_t mSize; public: - void init (uint8_t *aData, uint32_t aSize) + DWriteFontFileStream (uint8_t *aData, uint32_t aSize) { mData = aData; mSize = aSize; @@ -151,14 +151,11 @@ _hb_directwrite_shaper_face_data_create(hb_face_t *face) HRESULT hr; hb_blob_t *blob = hb_face_reference_blob (face); - DWriteFontFileStream *fontFileStream = (DWriteFontFileStream*) - malloc (sizeof (DWriteFontFileStream)); - fontFileStream->init ((uint8_t*) hb_blob_get_data (blob, nullptr), + DWriteFontFileStream *fontFileStream = new DWriteFontFileStream ( + (uint8_t *) hb_blob_get_data (blob, nullptr), hb_blob_get_length (blob)); - DWriteFontFileLoader *fontFileLoader = (DWriteFontFileLoader*) - malloc (sizeof (DWriteFontFileLoader)); - fontFileLoader->init (fontFileStream); + DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream); dwriteFactory->RegisterFontFileLoader (fontFileLoader); IDWriteFontFile *fontFile; @@ -216,9 +213,9 @@ _hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data data->dwriteFactory->Release (); } if (data->fontFileLoader) - free (data->fontFileLoader); + delete data->fontFileLoader; if (data->fontFileStream) - free (data->fontFileStream); + delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); if (data) @@ -924,7 +921,7 @@ hb_directwrite_shape_experimental_width(hb_font_t *font, unsigned int num_features, float width) { - static char *shapers = (char *) "directwrite"; + static const char *shapers = "directwrite"; hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, &shapers); hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer, commit 8d1b4082ae01b8fd87b2e83c89f670c1c7cfa0b1 Author: Ebrahim Byagowi <[email protected]> Date: Sat Mar 17 01:05:03 2018 +0330 Appropriate fix for msys2 bot fail on gen-def.py (#894) diff --git a/src/Makefile.am b/src/Makefile.am index d9947880..a81f1125 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -243,7 +243,7 @@ DISTCLEANFILES += \ $(HB_GOBJECT_ENUM_headers) \ $(NULL) hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS) - $(AM_V_GEN) $(GLIB_MKENUMS) \ + $(AM_V_GEN) PYTHONIOENCODING=UTF-8 $(GLIB_MKENUMS) \ --identifier-prefix hb_ --symbol-prefix hb_gobject \ --template $^ | \ sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \ diff --git a/src/gen-def.py b/src/gen-def.py index 74507e46..de35eb7d 100755 --- a/src/gen-def.py +++ b/src/gen-def.py @@ -7,7 +7,7 @@ import io, os, re, sys headers_content = [] for h in os.environ["headers"].split (' '): if h.endswith (".h"): - with io.open (h, encoding='ISO-8859-1') as f: headers_content.append (f.read ()) + with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ()) result = """EXPORTS %s commit 7b4333b090a3adf04519ec853456cafff07dedf0 Author: Ebrahim Byagowi <[email protected]> Date: Fri Mar 16 22:45:09 2018 +0330 Do feature test before adding -Bsymbolic-functions, autotools part (#892) diff --git a/configure.ac b/configure.ac index 2831e599..9e3bf081 100644 --- a/configure.ac +++ b/configure.ac @@ -94,7 +94,7 @@ AC_CHECK_ALIGNOF([struct{char;}]) if test "x$GCC" = "xyes"; then # Make symbols link locally - LDFLAGS="$LDFLAGS -Bsymbolic-functions" + AX_CHECK_LINK_FLAG([[-Bsymbolic-functions]], [LDFLAGS="$LDFLAGS -Bsymbolic-functions"]) # Assorted warnings CXXFLAGS="$CXXFLAGS -Wcast-align" diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 00000000..819409a2 --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <[email protected]> +# Copyright (c) 2011 Maarten Bosmans <[email protected]> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS commit d68f00e4d8b061f56d3bd46d5ed1bc51406a4f1a Author: Joel Winarske <[email protected]> Date: Fri Mar 16 12:14:27 2018 -0700 Do feature test before adding -Bsymbolic-functions, cmake part (#889) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ddc15a7..85709b2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -537,7 +537,11 @@ target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS}) if (UNIX OR MINGW) # Make symbols link locally - link_libraries(-Bsymbolic-functions) + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS) + if(CXX_SUPPORTS_FLAG_BSYMB_FUNCS) + link_libraries(-Bsymbolic-functions) + endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # Make sure we don't link to libstdc++ commit 42d3271cc39050c9df5f8c7345322ae90592158e Author: Ebrahim Byagowi <[email protected]> Date: Fri Mar 16 22:39:58 2018 +0330 [cmake] Don't hide symbols by default (#891) But keep use of cmake idiomatic way of making inlines hidden diff --git a/CMakeLists.txt b/CMakeLists.txt index b9796ebf..5ddc15a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,4 @@ cmake_minimum_required(VERSION 2.8.0) -# Allow symbol hiding for both static and shared libs. -cmake_policy(SET CMP0063 NEW) - project(harfbuzz) enable_testing() @@ -528,8 +525,6 @@ endif () ## Define harfbuzz library add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) set_target_properties(harfbuzz PROPERTIES - C_VISIBILITY_PRESET hidden - CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN TRUE) target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) @@ -537,8 +532,6 @@ target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) add_dependencies(harfbuzz-subset harfbuzz) set_target_properties(harfbuzz-subset PROPERTIES - C_VISIBILITY_PRESET hidden - CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN TRUE) target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS}) @@ -568,20 +561,14 @@ if (HB_HAVE_GOBJECT) ${hb_gobject_gen_headers} ) set_target_properties(harfbuzz-gobject PROPERTIES - C_VISIBILITY_PRESET hidden - CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN TRUE) include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src) add_dependencies(harfbuzz-gobject harfbuzz) target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS}) endif () -if (BUILD_SHARED_LIBS) - if (WIN32 AND NOT MINGW) - add_definitions("-DHB_EXTERN=__declspec(dllexport) extern") - else () - add_definitions("-DHB_EXTERN=__attribute__(( visibility( \"default\" ) )) extern") - endif () +if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW) + add_definitions("-DHB_EXTERN=__declspec(dllexport) extern") endif () # On Windows, g-ir-scanner requires a DLL build in order for it to work commit 584693e0cb3585a910b18d7916d7e554ecdf619a Author: Garret Rieger <[email protected]> Date: Thu Mar 15 18:27:01 2018 -0700 [subset] Test not linking libharfbuzz-subset-fuzzing into hb-subset-fuzzer. diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index a57f41dc..dc9f9016 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -55,7 +55,7 @@ hb_subset_fuzzer_SOURCES = \ main.cc \ $(NULL) hb_subset_fuzzer_LDADD = \ - $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \ + $(top_builddir)/src/libharfbuzz-fuzzing.la \ $(NULL) hb_subset_fuzzer_CPPFLAGS = \ $(AM_CPPFLAGS) \ diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc index 1e26d26a..c59a8e28 100644 --- a/test/fuzzing/hb-subset-fuzzer.cc +++ b/test/fuzzing/hb-subset-fuzzer.cc @@ -9,6 +9,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { printf ("hb-subset-fuzzer: input size = %zu\n", size); + /* hb_blob_t *blob = hb_blob_create ((const char *)data, size, HB_MEMORY_MODE_READONLY, NULL, NULL); hb_face_t *face = hb_face_create (blob, 0); @@ -34,6 +35,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) hb_subset_profile_destroy (profile); hb_face_destroy (face); hb_blob_destroy (blob); + */ return 0; } diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py index b0bb52ce..229881a4 100755 --- a/test/fuzzing/run-subset-fuzzer-tests.py +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -6,7 +6,7 @@ import sys, os, subprocess srcdir = os.environ.get ("srcdir", ".") EXEEXT = os.environ.get ("EXEEXT", "") top_builddir = os.environ.get ("top_builddir", ".") -hb_subset_fuzzer = os.path.join (top_builddir, "hb-shape-fuzzer" + EXEEXT) +hb_subset_fuzzer = os.path.join (top_builddir, "hb-subset-fuzzer" + EXEEXT) if not os.path.exists (hb_subset_fuzzer): if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]): commit 3f9361fe7a68896d2a5a44709ec08fe510144215 Author: Garret Rieger <[email protected]> Date: Thu Mar 15 18:06:15 2018 -0700 [subset] Test hb-shape-fuzzer in run-subset-fuzzer-tests. diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py index 229881a4..b0bb52ce 100755 --- a/test/fuzzing/run-subset-fuzzer-tests.py +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -6,7 +6,7 @@ import sys, os, subprocess srcdir = os.environ.get ("srcdir", ".") EXEEXT = os.environ.get ("EXEEXT", "") top_builddir = os.environ.get ("top_builddir", ".") -hb_subset_fuzzer = os.path.join (top_builddir, "hb-subset-fuzzer" + EXEEXT) +hb_subset_fuzzer = os.path.join (top_builddir, "hb-shape-fuzzer" + EXEEXT) if not os.path.exists (hb_subset_fuzzer): if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]): commit ce368e0d05147e70d8ad90383d748644b07f1d6f Author: Garret Rieger <[email protected]> Date: Thu Mar 15 18:04:54 2018 -0700 [subset] make libharfbuzz-subset-fuzzing.la depend on lib target. diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index 96b1cbf4..a57f41dc 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -11,6 +11,7 @@ lib: @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src fuzzing $(top_builddir)/src/libharfbuzz-fuzzing.la: lib +$(top_builddir)/src/libharfbuzz-subset-fuzzing.la: lib EXTRA_DIST += \ README \ commit 85a57029cdad634f56aa3ccc768e72bcb03888e3 Author: Garret Rieger <[email protected]> Date: Thu Mar 15 16:31:38 2018 -0700 [subset] %d -> %zu diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc index 863c495f..1e26d26a 100644 --- a/test/fuzzing/hb-subset-fuzzer.cc +++ b/test/fuzzing/hb-subset-fuzzer.cc @@ -8,7 +8,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - printf ("hb-subset-fuzzer: input size = %d\n", size); + printf ("hb-subset-fuzzer: input size = %zu\n", size); hb_blob_t *blob = hb_blob_create ((const char *)data, size, HB_MEMORY_MODE_READONLY, NULL, NULL); hb_face_t *face = hb_face_create (blob, 0); commit 318eea585329807477aab4eec173b561a08a46ca Author: Garret Rieger <[email protected]> Date: Thu Mar 15 16:14:01 2018 -0700 [subset] Add some more logging to hb-subset-fuzzer. diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc index dfa83613..863c495f 100644 --- a/test/fuzzing/hb-subset-fuzzer.cc +++ b/test/fuzzing/hb-subset-fuzzer.cc @@ -8,6 +8,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + printf ("hb-subset-fuzzer: input size = %d\n", size); hb_blob_t *blob = hb_blob_create ((const char *)data, size, HB_MEMORY_MODE_READONLY, NULL, NULL); hb_face_t *face = hb_face_create (blob, 0); commit 64bab8b3d009ed4327c2db9fa3425682de225810 Author: Garret Rieger <[email protected]> Date: Thu Mar 15 16:12:00 2018 -0700 [subset] Fix run-shape-fuzzer-tests.py. It was generating incorrect paths for input fonts. diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index 088b36a4..43378d1b 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -19,10 +19,12 @@ please provide it as the first argument to the tool""") print ('hb_shape_fuzzer:', hb_shape_fuzzer) fails = 0 -for line in open (os.path.join (srcdir, "..", "shaping", "data", "in-house", "tests", "fuzzed.tests")): +parent_path = os.path.join (srcdir, "..", "shaping", "data", "in-house", "tests") +for line in open (os.path.join (parent_path, "fuzzed.tests")): font = line.split (":")[0] + font_path = os.path.join (parent_path, font) - p = subprocess.Popen ([hb_shape_fuzzer, os.path.join (srcdir, "..", "shaping", font)]) + p = subprocess.Popen ([hb_shape_fuzzer, font_path]) if p.wait () != 0: fails = fails + 1 commit 6f9a584371ba4a9a63be3fa89f46474047a43ceb Author: Garret Rieger <[email protected]> Date: Thu Mar 15 15:41:08 2018 -0700 [subset] Add more verbose output for subset fuzzer test. diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index bf461acf..088b36a4 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -28,5 +28,5 @@ for line in open (os.path.join (srcdir, "..", "shaping", "data", "in-house", "te fails = fails + 1 if fails: - print ("%i fuzzer related tests failed." % fails) + print ("%i shape fuzzer related tests failed." % fails) sys.exit (1) diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py index 9450cb43..229881a4 100755 --- a/test/fuzzing/run-subset-fuzzer-tests.py +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -20,12 +20,16 @@ print ('hb_subset_fuzzer:', hb_subset_fuzzer) fails = 0 parent_path = os.path.join (srcdir, "..", "subset", "data", "fonts") +print ("running subset fuzzer against fonts in %s" % parent_path) for file in os.listdir (parent_path): - p = subprocess.Popen ([hb_subset_fuzzer, os.path.join(parent_path, file)]) + path = os.path.join(parent_path, file) + print ("running subset fuzzer against %s" % path) + p = subprocess.Popen ([hb_subset_fuzzer, path]) if p.wait () != 0: + print ("failed for %s" % path) fails = fails + 1 if fails: - print ("%i fuzzer related tests failed." % fails) + print ("%i subset fuzzer related tests failed." % fails) sys.exit (1) commit 0ce0f8781213f8f01b9ebc8cfa31434784899952 Author: Garret Rieger <[email protected]> Date: Thu Mar 15 13:04:31 2018 -0700 [subset] Rename hb-fuzzer -> hb-shape-fuzzer. diff --git a/test/fuzzing/CMakeLists.txt b/test/fuzzing/CMakeLists.txt index cb41dc18..577d13ce 100644 --- a/test/fuzzing/CMakeLists.txt +++ b/test/fuzzing/CMakeLists.txt @@ -1,25 +1,25 @@ if (HB_CHECK) file (READ "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.am" MAKEFILEAM) - extract_make_variable (hb_fuzzer_SOURCES ${MAKEFILEAM}) + extract_make_variable (hb_shape_fuzzer_SOURCES ${MAKEFILEAM}) extract_make_variable (hb_subset_fuzzer_SOURCES ${MAKEFILEAM}) # TODO: enable these two #extract_make_variable (FUZZING_CPPFLAGS ${MAKEFILEAM}) # extracting regex fail - #add_executable (hb-fuzzer # it should be run only after ragel execution + #add_executable (hb-shape-fuzzer # it should be run only after ragel execution # ${project_sources} ${project_extra_sources} ${project_headers} - # ${hb_fuzzer_SOURCES}) + # ${hb_shape_fuzzer_SOURCES}) - add_executable (hb-fuzzer ${hb_fuzzer_SOURCES}) - target_link_libraries (hb-fuzzer harfbuzz) + add_executable (hb-shape-fuzzer ${hb_shape_fuzzer_SOURCES}) + target_link_libraries (hb-shape-fuzzer harfbuzz) add_executable (hb-subset-fuzzer ${hb_subset_fuzzer_SOURCES}) target_link_libraries (hb-subset-fuzzer harfbuzz-subset) - target_compile_definitions(hb-fuzzer PUBLIC ${FUZZING_CPPFLAGS}) + target_compile_definitions(hb-shape-fuzzer PUBLIC ${FUZZING_CPPFLAGS}) target_compile_definitions(hb-subset-fuzzer PUBLIC ${FUZZING_CPPFLAGS}) - add_test (NAME hb-fuzzer - COMMAND "${PYTHON_EXECUTABLE}" run-fuzzer-tests.py $<TARGET_FILE:hb-fuzzer> + add_test (NAME hb-shape-fuzzer + COMMAND "${PYTHON_EXECUTABLE}" run-shape-fuzzer-tests.py $<TARGET_FILE:hb-shape-fuzzer> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) add_test (NAME hb-subset-fuzzer COMMAND "${PYTHON_EXECUTABLE}" run-subset-fuzzer-tests.py $<TARGET_FILE:hb-subset-fuzzer> diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index 06488206..96b1cbf4 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -14,13 +14,13 @@ $(top_builddir)/src/libharfbuzz-fuzzing.la: lib EXTRA_DIST += \ README \ - run-fuzzer-tests.py \ + run-shape-fuzzer-tests.py \ run-subset-fuzzer-tests.py \ CMakeLists.txt \ $(NULL) check_PROGRAMS = \ - hb-fuzzer \ + hb-shape-fuzzer \ hb-subset-fuzzer \ $(NULL) @@ -33,18 +33,18 @@ LDADD = \ $(top_builddir)/src/libharfbuzz-fuzzing.la \ $(NULL) -hb_fuzzer_SOURCES = \ +hb_shape_fuzzer_SOURCES = \ hb-fuzzer.hh \ - hb-fuzzer.cc \ + hb-shape-fuzzer.cc \ main.cc \ $(NULL) -hb_fuzzer_LDADD = \ +hb_shape_fuzzer_LDADD = \ $(LDADD) \ $(NULL) -hb_fuzzer_CPPFLAGS = \ +hb_shape_fuzzer_CPPFLAGS = \ $(AM_CPPFLAGS) \ $(NULL) -hb_fuzzer_DEPENDENCIES = \ +hb_shape_fuzzer_DEPENDENCIES = \ lib \ $(NULL) @@ -64,7 +64,7 @@ hb_subset_fuzzer_DEPENDENCIES = \ $(NULL) check: - EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-fuzzer-tests.py + EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py -include $(top_srcdir)/git.mk diff --git a/test/fuzzing/hb-fuzzer.cc b/test/fuzzing/hb-shape-fuzzer.cc similarity index 100% rename from test/fuzzing/hb-fuzzer.cc rename to test/fuzzing/hb-shape-fuzzer.cc diff --git a/test/fuzzing/run-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py similarity index 64% rename from test/fuzzing/run-fuzzer-tests.py rename to test/fuzzing/run-shape-fuzzer-tests.py index 9455a4b6..bf461acf 100755 --- a/test/fuzzing/run-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -6,23 +6,23 @@ import sys, os, subprocess srcdir = os.environ.get ("srcdir", ".") EXEEXT = os.environ.get ("EXEEXT", "") top_builddir = os.environ.get ("top_builddir", ".") -hb_fuzzer = os.path.join (top_builddir, "hb-fuzzer" + EXEEXT) +hb_shape_fuzzer = os.path.join (top_builddir, "hb-shape-fuzzer" + EXEEXT) -if not os.path.exists (hb_fuzzer): +if not os.path.exists (hb_shape_fuzzer): if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]): - print ("""Failed to find hb-fuzzer binary automatically, + print ("""Failed to find hb-shape-fuzzer binary automatically, please provide it as the first argument to the tool""") sys.exit (1) - hb_fuzzer = sys.argv[1] + hb_shape_fuzzer = sys.argv[1] -print ('hb_fuzzer:', hb_fuzzer) +print ('hb_shape_fuzzer:', hb_shape_fuzzer) fails = 0 for line in open (os.path.join (srcdir, "..", "shaping", "data", "in-house", "tests", "fuzzed.tests")): font = line.split (":")[0] - p = subprocess.Popen ([hb_fuzzer, os.path.join (srcdir, "..", "shaping", font)]) + p = subprocess.Popen ([hb_shape_fuzzer, os.path.join (srcdir, "..", "shaping", font)]) if p.wait () != 0: fails = fails + 1 commit 1e9bd6d5ff0af0189b6398c5e13cff11ee70762b Author: Garret Rieger <[email protected]> Date: Wed Mar 14 19:58:15 2018 -0700 [subset] Add rub-subset-fuzzer-tests.py to dist files. diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index d1f49e57..06488206 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -15,6 +15,7 @@ $(top_builddir)/src/libharfbuzz-fuzzing.la: lib EXTRA_DIST += \ README \ run-fuzzer-tests.py \ + run-subset-fuzzer-tests.py \ CMakeLists.txt \ $(NULL) commit 474afaafd908a9c8174e05d693ac214ef2cc2597 Author: Garret Rieger <[email protected]> Date: Wed Mar 14 19:15:33 2018 -0700 [subset] Add a test runner for hb-subset-fuzzer and cmake build config. diff --git a/test/fuzzing/CMakeLists.txt b/test/fuzzing/CMakeLists.txt index fe4cf790..cb41dc18 100644 --- a/test/fuzzing/CMakeLists.txt +++ b/test/fuzzing/CMakeLists.txt @@ -1,6 +1,7 @@ if (HB_CHECK) file (READ "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.am" MAKEFILEAM) extract_make_variable (hb_fuzzer_SOURCES ${MAKEFILEAM}) + extract_make_variable (hb_subset_fuzzer_SOURCES ${MAKEFILEAM}) # TODO: enable these two #extract_make_variable (FUZZING_CPPFLAGS ${MAKEFILEAM}) # extracting regex fail @@ -11,8 +12,16 @@ if (HB_CHECK) add_executable (hb-fuzzer ${hb_fuzzer_SOURCES}) target_link_libraries (hb-fuzzer harfbuzz) + add_executable (hb-subset-fuzzer ${hb_subset_fuzzer_SOURCES}) + target_link_libraries (hb-subset-fuzzer harfbuzz-subset) + target_compile_definitions(hb-fuzzer PUBLIC ${FUZZING_CPPFLAGS}) + target_compile_definitions(hb-subset-fuzzer PUBLIC ${FUZZING_CPPFLAGS}) + add_test (NAME hb-fuzzer COMMAND "${PYTHON_EXECUTABLE}" run-fuzzer-tests.py $<TARGET_FILE:hb-fuzzer> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + add_test (NAME hb-subset-fuzzer + COMMAND "${PYTHON_EXECUTABLE}" run-subset-fuzzer-tests.py $<TARGET_FILE:hb-subset-fuzzer> + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif () diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index 27f59d9d..d1f49e57 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -48,7 +48,7 @@ hb_fuzzer_DEPENDENCIES = \ $(NULL) hb_subset_fuzzer_SOURCES = \ - hb-subset.hh \ + hb-fuzzer.hh \ hb-subset-fuzzer.cc \ main.cc \ $(NULL) @@ -64,5 +64,6 @@ hb_subset_fuzzer_DEPENDENCIES = \ check: EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-fuzzer-tests.py + EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py -include $(top_srcdir)/git.mk diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py new file mode 100755 index 00000000..9450cb43 --- /dev/null +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +from __future__ import print_function +import sys, os, subprocess + +srcdir = os.environ.get ("srcdir", ".") +EXEEXT = os.environ.get ("EXEEXT", "") +top_builddir = os.environ.get ("top_builddir", ".") +hb_subset_fuzzer = os.path.join (top_builddir, "hb-subset-fuzzer" + EXEEXT) + +if not os.path.exists (hb_subset_fuzzer): + if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]): + print ("""Failed to find hb-subset-fuzzer binary automatically, +please provide it as the first argument to the tool""") + sys.exit (1) + + hb_subset_fuzzer = sys.argv[1] + +print ('hb_subset_fuzzer:', hb_subset_fuzzer) +fails = 0 + +parent_path = os.path.join (srcdir, "..", "subset", "data", "fonts") +for file in os.listdir (parent_path): + p = subprocess.Popen ([hb_subset_fuzzer, os.path.join(parent_path, file)]) + + if p.wait () != 0: + fails = fails + 1 + +if fails: + print ("%i fuzzer related tests failed." % fails) + sys.exit (1) commit aa9612d35f59f7f269fba4797c8da491844c56ec Author: Garret Rieger <[email protected]> Date: Mon Mar 12 18:04:34 2018 -0700 [subset] Fix fuzzing build for hb-subset-fuzzer. diff --git a/src/Makefile.am b/src/Makefile.am index 4d1f237d..d9947880 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -184,7 +184,8 @@ FUZZING_CPPFLAGS = \ -DHB_BUFFER_MAX_OPS_MIN=64 \ -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ $(NULL) -EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la +EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la + libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS) libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES) libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) @@ -193,23 +194,9 @@ libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) CLEANFILES += libharfbuzz-fuzzing.la -SUBSET_FUZZING_CPPFLAGS = \ - -DHB_NDEBUG \ - -DHB_MAX_NESTING_LEVEL=3 \ - -DHB_SANITIZE_MAX_EDITS=3 \ - -DHB_SANITIZE_MAX_OPS_FACTOR=3 \ - -DHB_SANITIZE_MAX_OPS_MIN=128 \ - -DHB_BUFFER_MAX_LEN_FACTOR=3 \ - -DHB_BUFFER_MAX_LEN_MIN=8 \ - -DHB_BUFFER_MAX_LEN_DEFAULT=128 \ - -DHB_BUFFER_MAX_OPS_FACTOR=8 \ - -DHB_BUFFER_MAX_OPS_MIN=64 \ - -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ - $(NULL) -EXTRA_LTLIBRARIES = libharfbuzz-subset-fuzzing.la libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS) libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES) -libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(SUBSET_FUZZING_CPPFLAGS) +libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD) EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index 638f2f0d..27f59d9d 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -50,6 +50,7 @@ hb_fuzzer_DEPENDENCIES = \ hb_subset_fuzzer_SOURCES = \ hb-subset.hh \ hb-subset-fuzzer.cc \ + main.cc \ $(NULL) hb_subset_fuzzer_LDADD = \ $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \ commit b674fc1f9fa36857214ddaba3d32877f03ffec8c Author: Garret Rieger <[email protected]> Date: Mon Mar 12 16:33:47 2018 -0700 [subset] Add missing destroy of subsetting result in subset fuzzer. diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc index 3081a57c..dfa83613 100644 --- a/test/fuzzing/hb-subset-fuzzer.cc +++ b/test/fuzzing/hb-subset-fuzzer.cc @@ -28,6 +28,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) hb_face_t *result = hb_subset (face, profile, input); + hb_face_destroy (result); hb_subset_input_destroy (input); hb_subset_profile_destroy (profile); hb_face_destroy (face); commit 1beb08862e9bd668599f0385d7ba59272fc24912 Author: Garret Rieger <[email protected]> Date: Mon Mar 12 16:08:16 2018 -0700 [subset] First pass at setting up a fuzzing program for hb-subset. diff --git a/src/Makefile.am b/src/Makefile.am index afa104b8..4d1f237d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ check_PROGRAMS = # Convenience targets: lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la -fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la +fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la lib_LTLIBRARIES = libharfbuzz.la @@ -193,6 +193,28 @@ libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) CLEANFILES += libharfbuzz-fuzzing.la +SUBSET_FUZZING_CPPFLAGS = \ + -DHB_NDEBUG \ + -DHB_MAX_NESTING_LEVEL=3 \ + -DHB_SANITIZE_MAX_EDITS=3 \ + -DHB_SANITIZE_MAX_OPS_FACTOR=3 \ + -DHB_SANITIZE_MAX_OPS_MIN=128 \ + -DHB_BUFFER_MAX_LEN_FACTOR=3 \ + -DHB_BUFFER_MAX_LEN_MIN=8 \ + -DHB_BUFFER_MAX_LEN_DEFAULT=128 \ + -DHB_BUFFER_MAX_OPS_FACTOR=8 \ + -DHB_BUFFER_MAX_OPS_MIN=64 \ + -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ + $(NULL) +EXTRA_LTLIBRARIES = libharfbuzz-subset-fuzzing.la +libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS) +libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES) +libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(SUBSET_FUZZING_CPPFLAGS) +libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) +libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD) +EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) +CLEANFILES += libharfbuzz-subset-fuzzing.la + if HAVE_ICU if HAVE_ICU_BUILTIN HBCFLAGS += $(ICU_CFLAGS) diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index a7f73623..638f2f0d 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -20,6 +20,7 @@ EXTRA_DIST += \ check_PROGRAMS = \ hb-fuzzer \ + hb-subset-fuzzer \ $(NULL) AM_CPPFLAGS = \ @@ -46,6 +47,20 @@ hb_fuzzer_DEPENDENCIES = \ lib \ $(NULL) +hb_subset_fuzzer_SOURCES = \ + hb-subset.hh \ + hb-subset-fuzzer.cc \ + $(NULL) +hb_subset_fuzzer_LDADD = \ + $(top_builddir)/src/libharfbuzz-subset-fuzzing.la \ + $(NULL) +hb_subset_fuzzer_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(NULL) +hb_subset_fuzzer_DEPENDENCIES = \ + lib \ + $(NULL) + check: EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-fuzzer-tests.py diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc new file mode 100644 index 00000000..3081a57c --- /dev/null +++ b/test/fuzzing/hb-subset-fuzzer.cc @@ -0,0 +1,37 @@ +#include "hb-fuzzer.hh" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "hb-subset.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + hb_blob_t *blob = hb_blob_create ((const char *)data, size, + HB_MEMORY_MODE_READONLY, NULL, NULL); + hb_face_t *face = hb_face_create (blob, 0); + hb_subset_profile_t *profile = hb_subset_profile_create (); + // TODO(grieger): Loop through common profiles (hints, no hints, etc.) + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t *codepoints = hb_subset_input_unicode_set (input); + + const hb_codepoint_t text[] = + { + 'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2', + '3', '@', '_', '%', '&', ')', '*', '$', '!' + }; + for (int i = 0; i < sizeof (text) / sizeof (hb_codepoint_t); i++) + { + hb_set_add (codepoints, text[i]); + } + + hb_face_t *result = hb_subset (face, profile, input); + + hb_subset_input_destroy (input); + hb_subset_profile_destroy (profile); + hb_face_destroy (face); + hb_blob_destroy (blob); + + return 0; +} _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
