From 189f65344a9c34618ecc11af30591165f8ff24d0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 13 Feb 2022 13:22:08 -0600 Subject: [PATCH 1/3] [fuzz-shape] Verify shape output Let the fuzzers loose on shape verify. --- test/fuzzing/hb-shape-fuzzer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fuzzing/hb-shape-fuzzer.cc b/test/fuzzing/hb-shape-fuzzer.cc index 0022a89ec..09bc1b43d 100644 --- a/test/fuzzing/hb-shape-fuzzer.cc +++ b/test/fuzzing/hb-shape-fuzzer.cc @@ -33,7 +33,7 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) { const char text[] = "ABCDEXYZ123@_%&)*$!"; hb_buffer_t *buffer = hb_buffer_create (); - // hb_buffer_set_flags (buffer, HB_BUFFER_FLAG_VERIFY); + hb_buffer_set_flags (buffer, HB_BUFFER_FLAG_VERIFY); hb_buffer_add_utf8 (buffer, text, -1, 0, -1); hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, nullptr, 0); From 5a058ba15837be53d8835031a689c22e369531b2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 31 May 2022 05:35:17 -0600 Subject: [PATCH 2/3] [shape-fuzzer] Add commented out more buffer-verify option Those currently fail and I've been unable to debug them. I tried two, passing them to hb-shape doesn't reproduce the failure. :( --- test/fuzzing/hb-shape-fuzzer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fuzzing/hb-shape-fuzzer.cc b/test/fuzzing/hb-shape-fuzzer.cc index 09bc1b43d..ce6e356e0 100644 --- a/test/fuzzing/hb-shape-fuzzer.cc +++ b/test/fuzzing/hb-shape-fuzzer.cc @@ -33,7 +33,7 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) { const char text[] = "ABCDEXYZ123@_%&)*$!"; hb_buffer_t *buffer = hb_buffer_create (); - hb_buffer_set_flags (buffer, HB_BUFFER_FLAG_VERIFY); + hb_buffer_set_flags (buffer, (hb_buffer_flags_t) (HB_BUFFER_FLAG_VERIFY /* | HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT */)); hb_buffer_add_utf8 (buffer, text, -1, 0, -1); hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, nullptr, 0); @@ -51,7 +51,7 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) text32[10] = test_font (font, text32[15]) % 256; hb_buffer_t *buffer = hb_buffer_create (); -// hb_buffer_set_flags (buffer, HB_BUFFER_FLAG_VERIFY); + // hb_buffer_set_flags (buffer, (hb_buffer_flags_t) (HB_BUFFER_FLAG_VERIFY | HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)); hb_buffer_add_utf32 (buffer, text32, sizeof (text32) / sizeof (text32[0]), 0, -1); hb_buffer_guess_segment_properties (buffer); hb_shape (font, buffer, nullptr, 0); From e246723f0c796ec5207e1b64dd7a409cebb91d99 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 1 Jun 2022 04:54:18 -0600 Subject: [PATCH 3/3] [shape] Fail shaping internally if buffer ops exceeded --- src/hb-buffer.cc | 2 ++ src/hb-ot-shape.cc | 2 -- src/hb-shape.cc | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index bd786f9f4..4c030eb50 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -311,6 +311,7 @@ hb_buffer_t::enter () { deallocate_var_all (); serial = 0; + shaping_failed = false; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR))) { @@ -330,6 +331,7 @@ hb_buffer_t::leave () max_ops = HB_BUFFER_MAX_OPS_DEFAULT; deallocate_var_all (); serial = 0; + // Intentionally not reseting shaping_failed, such that it can be inspected. } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 99aadab3f..aa07c5914 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -1159,8 +1159,6 @@ hb_propagate_flags (hb_buffer_t *buffer) static void hb_ot_shape_internal (hb_ot_shape_context_t *c) { - c->buffer->enter (); - /* Save the original direction, we use it later. */ c->target_direction = c->buffer->props.direction; diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 3534921ef..9c1e9c52b 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -129,6 +129,8 @@ hb_shape_full (hb_font_t *font, if (unlikely (!buffer->len)) return true; + buffer->enter (); + hb_buffer_t *text_buffer = nullptr; if (buffer->flags & HB_BUFFER_FLAG_VERIFY) { @@ -140,8 +142,12 @@ hb_shape_full (hb_font_t *font, features, num_features, font->coords, font->num_coords, shaper_list); - buffer->shaping_failed = false; + hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); + + if (buffer->max_ops <= 0) + buffer->shaping_failed = true; + hb_shape_plan_destroy (shape_plan); if (text_buffer) @@ -157,6 +163,8 @@ hb_shape_full (hb_font_t *font, hb_buffer_destroy (text_buffer); } + buffer->leave (); + return res; }