| /* | |
| * Copyright © 2026 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-test.h" | |
| #include <hb-ot.h> | |
| #include <hb-aat.h> | |
| /* Regression test for GHSA-v5mv-8hhw-vff8: the "list getter" APIs document | |
| * their output array as nullable ("may be NULL"; pass NULL to just query the | |
| * count). Passing a NULL output array together with a non-NULL count on a | |
| * populated table used to write through the NULL pointer and crash. Each case | |
| * below calls the getter with a non-NULL count and a NULL output array on a | |
| * font whose table is populated, and checks it returns the total without | |
| * crashing. */ | |
| static void | |
| test_nullable_output_cpal_colors (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf"); | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_ot_color_palette_get_colors (face, 0, 0, &count, NULL), ==, 2); | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_colr_layers (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v1.ttf"); | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_ot_color_glyph_get_layers (face, 2, 0, &count, NULL), ==, 2); | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_meta_entries (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf"); | |
| unsigned int count = 100; | |
| unsigned int total = hb_ot_meta_get_entry_tags (face, 0, &count, NULL); | |
| g_assert_cmpuint (total, >, 0); | |
| hb_face_destroy (face); | |
| } | |
| #ifndef HB_NO_AAT | |
| static void | |
| test_nullable_output_aat_feature_types (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_aat_layout_get_feature_types (face, 0, &count, NULL), ==, 11); | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_aat_selector_infos (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf"); | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_aat_layout_feature_type_get_selector_infos ( | |
| face, HB_AAT_LAYOUT_FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE, | |
| 0, &count, NULL, NULL), ==, 4); | |
| hb_face_destroy (face); | |
| } | |
| #endif | |
| static void | |
| test_nullable_output_cv_characters (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/cv01.otf"); | |
| unsigned int feature_index; | |
| if (hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, 0, | |
| HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, | |
| HB_TAG ('c','v','0','1'), &feature_index)) | |
| { | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, | |
| feature_index, 0, | |
| &count, NULL), ==, 2); | |
| } | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_gsub_alternates (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf"); | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_ot_layout_lookup_get_glyph_alternates (face, 1, 1091, 0, | |
| &count, NULL), ==, 7); | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_table_tags (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf"); | |
| unsigned int count = 100; | |
| unsigned int total = hb_face_get_table_tags (face, 0, &count, NULL); | |
| g_assert_cmpuint (total, >, 0); | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_var_axis_infos (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/AdobeVFPrototype.abc.otf"); | |
| unsigned int count = 100; | |
| unsigned int total = hb_ot_var_get_axis_infos (face, 0, &count, NULL); | |
| g_assert_cmpuint (total, >, 0); | |
| hb_face_destroy (face); | |
| } | |
| static void | |
| test_nullable_output_math_kernings (void) | |
| { | |
| hb_face_t *face = hb_test_open_font_file ("fonts/MathTestFontFull.otf"); | |
| hb_font_t *font = hb_font_create (face); | |
| hb_codepoint_t glyph; | |
| if (hb_font_get_glyph_from_name (font, "I", -1, &glyph)) | |
| { | |
| unsigned int count = 100; | |
| g_assert_cmpuint (hb_ot_math_get_glyph_kernings (font, glyph, | |
| HB_OT_MATH_KERN_TOP_RIGHT, | |
| 0, &count, NULL), ==, 10); | |
| } | |
| hb_font_destroy (font); | |
| hb_face_destroy (face); | |
| } | |
| int | |
| main (int argc, char **argv) | |
| { | |
| hb_test_init (&argc, &argv); | |
| hb_test_add (test_nullable_output_cpal_colors); | |
| hb_test_add (test_nullable_output_colr_layers); | |
| hb_test_add (test_nullable_output_meta_entries); | |
| #ifndef HB_NO_AAT | |
| hb_test_add (test_nullable_output_aat_feature_types); | |
| hb_test_add (test_nullable_output_aat_selector_infos); | |
| #endif | |
| hb_test_add (test_nullable_output_cv_characters); | |
| hb_test_add (test_nullable_output_gsub_alternates); | |
| hb_test_add (test_nullable_output_table_tags); | |
| hb_test_add (test_nullable_output_var_axis_infos); | |
| hb_test_add (test_nullable_output_math_kernings); | |
| return hb_test_run (); | |
| } |