blob: b54a6d5f0a3fb57c4015c9b76007de93293ccb17 [file] [edit]
/*
* Copyright © 2022 Behdad Esfahbod
*
* 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.
*/
#include "hb.hh"
#include "OT/Color/COLR/COLR.hh"
static void
test_colr_valid_control ()
{
hb_set_t glyphs, layers, palettes, vars;
OT::hb_colrv1_closure_context_t ctx (nullptr, &glyphs, &layers, &palettes, &vars);
ctx.add_layer_indices (2, 3);
hb_always_assert (layers.get_population () == 3 && layers.has (2) && layers.has (4));
ctx.add_var_idxes (5, 2);
hb_always_assert (vars.get_population () == 2 && vars.has (5) && vars.has (6));
const uint8_t clip_bytes[13] = {
2, 0, 10, 0, 20, 0, 100, 0, 120, 0, 0, 0, 10
};
vars.clear ();
reinterpret_cast<const OT::ClipBoxFormat2 *> (clip_bytes)->closurev1 (&ctx);
hb_always_assert (vars.get_population () == 4 && vars.has (10) && vars.has (13));
}
static void
test_colr_add_layer_indices_overflow ()
{
hb_set_t glyphs, layers, palettes, vars;
OT::hb_colrv1_closure_context_t ctx (nullptr, &glyphs, &layers, &palettes, &vars);
ctx.add_layer_indices (0, 0);
hb_always_assert (layers.is_empty ());
ctx.add_layer_indices (hb_set_t::INVALID, 2);
hb_always_assert (layers.is_empty ());
/* 0xFFFFFFFE + 2 - 1 == INVALID must clamp last to INVALID - 1. */
ctx.add_layer_indices (0xFFFFFFFEu, 2);
hb_always_assert (layers.get_population () == 1 && layers.has (0xFFFFFFFEu));
/* 0xFFFFFFFD + 5 - 1 wraps 32-bit unsigned; must clamp to [0xFFFFFFFD..0xFFFFFFFE]. */
layers.clear ();
ctx.add_layer_indices (0xFFFFFFFDu, 5);
hb_always_assert (layers.get_population () == 2 &&
layers.has (0xFFFFFFFDu) &&
layers.has (0xFFFFFFFEu));
}
static void
test_colr_add_var_idxes_overflow ()
{
hb_set_t glyphs, layers, palettes, vars;
OT::hb_colrv1_closure_context_t ctx (nullptr, &glyphs, &layers, &palettes, &vars);
ctx.add_var_idxes (0, 0);
hb_always_assert (vars.is_empty ());
ctx.add_var_idxes (OT::VarIdx::NO_VARIATION, 4);
hb_always_assert (vars.is_empty ());
/* 0xFFFFFFFE + 2 - 1 == NO_VARIATION must clamp last to NO_VARIATION - 1. */
ctx.add_var_idxes (0xFFFFFFFEu, 2);
hb_always_assert (vars.get_population () == 1 && vars.has (0xFFFFFFFEu));
/* 0xFFFFFFFC + 6 - 1 wraps 32-bit unsigned; must clamp to [0xFFFFFFFC..0xFFFFFFFE]. */
vars.clear ();
ctx.add_var_idxes (0xFFFFFFFCu, 6);
hb_always_assert (vars.get_population () == 3 &&
vars.has (0xFFFFFFFCu) &&
vars.has (0xFFFFFFFDu) &&
vars.has (0xFFFFFFFEu));
}
static void
test_colr_clipbox_closure_overflow ()
{
hb_set_t glyphs, layers, palettes, vars;
OT::hb_colrv1_closure_context_t ctx (nullptr, &glyphs, &layers, &palettes, &vars);
uint8_t clip_bytes[13] = {
2, 0, 10, 0, 20, 0, 110, 0, 120, 0xFF, 0xFF, 0xFF, 0xFF
};
const auto *clip = reinterpret_cast<const OT::ClipBoxFormat2 *> (clip_bytes);
/* varIdxBase == NO_VARIATION: no variation indices added. */
clip->closurev1 (&ctx);
hb_always_assert (vars.is_empty ());
/* varIdxBase == 0xFFFFFFFC: +3 hits NO_VARIATION; must retain [0xFFFFFFFC..0xFFFFFFFE]. */
clip_bytes[12] = 0xFC;
clip->closurev1 (&ctx);
hb_always_assert (vars.get_population () == 3 &&
vars.has (0xFFFFFFFCu) &&
vars.has (0xFFFFFFFDu) &&
vars.has (0xFFFFFFFEu));
/* varIdxBase == 0xFFFFFFFE: +3 wraps 32-bit to 1; must retain {0xFFFFFFFE}. */
vars.clear ();
clip_bytes[12] = 0xFE;
clip->closurev1 (&ctx);
hb_always_assert (vars.get_population () == 1 && vars.has (0xFFFFFFFEu));
}
int
main (int argc, char **argv)
{
test_colr_valid_control ();
test_colr_add_layer_indices_overflow ();
test_colr_add_var_idxes_overflow ();
test_colr_clipbox_closure_overflow ();
return 0;
}