src/hb-blob.cc | 44 +++++++++++++++++++++++++++++++++++++++++++- util/helper-cairo.cc | 14 ++++++++++---- util/options.cc | 8 +++++--- util/options.hh | 2 ++ 4 files changed, 60 insertions(+), 8 deletions(-)
New commits: commit 941f2b85489b344698bf036922c589483034a7f2 Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Mon Jun 18 20:35:40 2018 +0430 Support pipe and friends on hb_blob_create_from_file (#1061) With this hb-view/hb-shape support pipes and possibly socket and named pipe also, anything fails just on mmap. We can later do the same for Windows also. This however reveals two issues, the fact most of our bots don't have HAVE_MMAP and using this instead the other fread/fopen reader can make failure on CI. I should look at them separately this change however is very low risk I believe. diff --git a/src/hb-blob.cc b/src/hb-blob.cc index c138648c..77dbc715 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -499,6 +499,36 @@ hb_blob_t::try_make_writable (void) # define MAP_NORESERVE 0 #endif +static hb_blob_t * +_fread_to_end (FILE *file) +{ + int allocated = BUFSIZ * 16; + char *blob = (char *) malloc (allocated); + if (blob == nullptr) return hb_blob_get_empty (); + + int len = 0; + while (!feof (file)) + { + if (allocated - len < BUFSIZ) + { + allocated *= 2; + char *new_blob = (char *) realloc (blob, allocated); + if (unlikely (!new_blob)) goto fail; + blob = new_blob; + } + + len += fread (blob + len, 1, allocated - len, file); + if (ferror (file)) goto fail; + } + + return hb_blob_create (blob, len, HB_MEMORY_MODE_WRITABLE, blob, + (hb_destroy_func_t) free); + +fail: + free (blob); + return hb_blob_get_empty (); +} + struct hb_mapped_file_t { char *contents; @@ -557,7 +587,19 @@ hb_blob_create_from_file (const char *file_name) writable ? PROT_READ|PROT_WRITE : PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0); - if (unlikely (file->contents == MAP_FAILED)) goto fail; + if (unlikely (file->contents == MAP_FAILED)) + { + free (file); + FILE *f = fdopen (fd, "rb"); + if (unlikely (f == nullptr)) + { + CLOSE (fd); + return hb_blob_get_empty (); + } + hb_blob_t *blob = _fread_to_end (f); + fclose (f); + return blob; + } #elif defined(_WIN32) || defined(__CYGWIN__) HANDLE fd = CreateFile (file_name, commit d0c2889dfc43da92c76d6eab5482b1298744dc9c Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Mon Jun 18 19:59:33 2018 +0430 Revert file blob sanitization and index checking (#1062) As https://github.com/harfbuzz/harfbuzz/pull/1059#issuecomment-397912812 we like to still work with blobs that harfbuzz itself can't handle directly that are failing sanitization currently apparently. diff --git a/util/options.cc b/util/options.cc index 299466fe..682e40c4 100644 --- a/util/options.cc +++ b/util/options.cc @@ -670,16 +670,8 @@ font_options_t::get_font (void) const blob = hb_blob_create_from_file (font_file); } - if (hb_blob_get_length (blob) == 0) - fail (false, "No such file or directory, or is empty"); - - unsigned int face_count = hb_face_count (blob); - - if (face_count == 0) - fail (false, "Not a font file"); // most likely - - if (face_index > face_count) - fail (false, "The requested font index wasn't available in the file"); + if (blob == hb_blob_get_empty ()) + fail (false, "No such file or directory"); /* Create the face */ hb_face_t *face = hb_face_create (blob, face_index); diff --git a/util/options.hh b/util/options.hh index 5287395a..2160d5ec 100644 --- a/util/options.hh +++ b/util/options.hh @@ -485,7 +485,7 @@ struct font_options_t : option_group_t mutable double font_size_y; char *font_funcs; -private: + private: mutable hb_font_t *font; }; commit c53697d3f2a3fae8b68ec4c5146c7000a07e0963 Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Sun Jun 17 17:04:55 2018 +0430 Verbose fail when something is wrong with hb-shape/hb-view input font file (#1059) This checks if the blob isn't empty and uses `hb_face_count` to see if the font file passes the simple font file sanitization so can detect if the input is actually a font and checks also whether input font-index is out of range. diff --git a/util/options.cc b/util/options.cc index 4c65735f..299466fe 100644 --- a/util/options.cc +++ b/util/options.cc @@ -670,6 +670,17 @@ font_options_t::get_font (void) const blob = hb_blob_create_from_file (font_file); } + if (hb_blob_get_length (blob) == 0) + fail (false, "No such file or directory, or is empty"); + + unsigned int face_count = hb_face_count (blob); + + if (face_count == 0) + fail (false, "Not a font file"); // most likely + + if (face_index > face_count) + fail (false, "The requested font index wasn't available in the file"); + /* Create the face */ hb_face_t *face = hb_face_create (blob, face_index); hb_blob_destroy (blob); commit aa0c5df4199ef4e96df2b856c8f629e49fdd5120 Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Sun Jun 17 16:49:34 2018 +0430 Fix reading fonts from stdin (#1060) We were passing the font path directly to freetype so rendering was broken when we are getting the font from stdin. This fixes it by using FT_New_Memory_Face instead. This fixes: * build/util/hb-view /dev/stdin text < font.ttf * build/util/hb-view - text < font.ttf * cat font.ttf | build/util/hb-view - text but doesn't work on * cat font.ttf | build/util/hb-view /dev/stdin text which I will try to fix separately. diff --git a/util/helper-cairo.cc b/util/helper-cairo.cc index b9f49851..3eaf90a7 100644 --- a/util/helper-cairo.cc +++ b/util/helper-cairo.cc @@ -89,10 +89,16 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts) atexit (free_ft_library); #endif } - FT_New_Face (ft_library, - font_opts->font_file, - font_opts->face_index, - &ft_face); + + unsigned int blob_length; + const char *blob_data = hb_blob_get_data (font_opts->blob, &blob_length); + + if (FT_New_Memory_Face (ft_library, + (const FT_Byte *) blob_data, + blob_length, + font_opts->face_index, + &ft_face)) + fail (false, "FT_New_Memory_Face fail"); } if (!ft_face) { diff --git a/util/options.cc b/util/options.cc index 24dc41f2..4c65735f 100644 --- a/util/options.cc +++ b/util/options.cc @@ -643,8 +643,6 @@ font_options_t::get_font (void) const if (font) return font; - hb_blob_t *blob = nullptr; - /* Create the blob */ if (!font_file) fail (true, "No font file set"); @@ -663,8 +661,9 @@ font_options_t::get_font (void) const strerror (errno)); g_string_append_len (gs, buf, ret); } + unsigned int len = gs->len; char *font_data = g_string_free (gs, false); - blob = hb_blob_create (font_data, gs->len, + blob = hb_blob_create (font_data, len, HB_MEMORY_MODE_WRITABLE, font_data, (hb_destroy_func_t) g_free); } else { diff --git a/util/options.hh b/util/options.hh index 8dfc8420..5287395a 100644 --- a/util/options.hh +++ b/util/options.hh @@ -455,6 +455,7 @@ struct font_options_t : option_group_t font_size_x = font_size_y = default_font_size; font_funcs = nullptr; + blob = nullptr; font = nullptr; add_options (parser); @@ -471,6 +472,7 @@ struct font_options_t : option_group_t hb_font_t *get_font (void) const; char *font_file; + mutable hb_blob_t *blob; int face_index; hb_variation_t *variations; unsigned int num_variations; @@ -483,7 +485,7 @@ struct font_options_t : option_group_t mutable double font_size_y; char *font_funcs; - private: +private: mutable hb_font_t *font; }; _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz