diff --git a/src/Makefile.sources b/src/Makefile.sources index 6e29b3f97..fde872093 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -49,6 +49,8 @@ HB_BASE_sources = \ hb-meta.hh \ hb-mutex.hh \ hb-null.hh \ + hb-number.cc \ + hb-number.hh \ hb-object.hh \ hb-open-file.hh \ hb-open-type.hh \ diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc index d338d1735..fe1c36023 100644 --- a/src/harfbuzz.cc +++ b/src/harfbuzz.cc @@ -8,6 +8,7 @@ #include "hb-fallback-shape.cc" #include "hb-font.cc" #include "hb-map.cc" +#include "hb-number.cc" #include "hb-ot-cff1-table.cc" #include "hb-ot-cff2-table.cc" #include "hb-ot-color.cc" diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc index d1bcf4dc0..518004ba9 100644 --- a/src/hb-buffer-serialize.cc +++ b/src/hb-buffer-serialize.cc @@ -25,6 +25,7 @@ */ #include "hb.hh" +#include "hb-number.hh" #ifndef HB_NO_BUFFER_SERIALIZE @@ -379,43 +380,27 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, } } - -static hb_bool_t -parse_uint (const char *pp, const char *end, uint32_t *pv) +static bool +parse_int (const char *pp, const char *end, int32_t *pv) { - char buf[32]; - unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); - strncpy (buf, pp, len); - buf[len] = '\0'; + int v; + const char *p = pp; + if (!hb_parse_int (&p, end, &v)) + return false; - char *p = buf; - char *pend = p; - uint32_t v; - - errno = 0; - v = strtol (p, &pend, 10); - if (errno || p == pend || pend - p != end - pp) + /* Check if parser consumed all of the buffer */ + if (p != end) return false; *pv = v; return true; } -static hb_bool_t -parse_int (const char *pp, const char *end, int32_t *pv) +static bool +parse_uint (const char *pp, const char *end, uint32_t *pv) { - char buf[32]; - unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp)); - strncpy (buf, pp, len); - buf[len] = '\0'; - - char *p = buf; - char *pend = p; int32_t v; - - errno = 0; - v = strtol (p, &pend, 10); - if (errno || p == pend || pend - p != end - pp) + if (!parse_int (pp, end, &v)) return false; *pv = v; diff --git a/src/hb-common.cc b/src/hb-common.cc index d96f3973f..f5c18ec58 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -27,8 +27,8 @@ */ #include "hb.hh" - #include "hb-machinery.hh" +#include "hb-number.hh" #include #ifdef HAVE_XLOCALE_H @@ -722,131 +722,26 @@ parse_char (const char **pp, const char *end, char c) static bool parse_uint (const char **pp, const char *end, unsigned int *pv) { - char buf[32]; - unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); - strncpy (buf, *pp, len); - buf[len] = '\0'; - - char *p = buf; - char *pend = p; - unsigned int v; - - /* Intentionally use strtol instead of strtoul, such that + /* Intentionally use strtol inside instead of strtoul, such that * -1 turns into "big number"... */ - errno = 0; - v = strtol (p, &pend, 10); - if (errno || p == pend) + int v; + if (!hb_parse_int (pp, end, &v)) return false; *pv = v; - *pp += pend - p; return true; } static bool parse_uint32 (const char **pp, const char *end, uint32_t *pv) { - char buf[32]; - unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); - strncpy (buf, *pp, len); - buf[len] = '\0'; - - char *p = buf; - char *pend = p; - unsigned int v; - - /* Intentionally use strtol instead of strtoul, such that + /* Intentionally use strtol inside instead of strtoul, such that * -1 turns into "big number"... */ - errno = 0; - v = strtol (p, &pend, 10); - if (errno || p == pend) + int v; + if (!hb_parse_int (pp, end, &v)) return false; *pv = v; - *pp += pend - p; - return true; -} - -#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L) -#define USE_XLOCALE 1 -#define HB_LOCALE_T locale_t -#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr) -#define HB_FREE_LOCALE(loc) freelocale (loc) -#elif defined(_MSC_VER) -#define USE_XLOCALE 1 -#define HB_LOCALE_T _locale_t -#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName) -#define HB_FREE_LOCALE(loc) _free_locale (loc) -#define strtod_l(a, b, c) _strtod_l ((a), (b), (c)) -#endif - -#ifdef USE_XLOCALE - -#if HB_USE_ATEXIT -static void free_static_C_locale (); -#endif - -static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t, - hb_C_locale_lazy_loader_t> -{ - static HB_LOCALE_T create () - { - HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C"); - -#if HB_USE_ATEXIT - atexit (free_static_C_locale); -#endif - - return C_locale; - } - static void destroy (HB_LOCALE_T p) - { - HB_FREE_LOCALE (p); - } - static HB_LOCALE_T get_null () - { - return nullptr; - } -} static_C_locale; - -#if HB_USE_ATEXIT -static -void free_static_C_locale () -{ - static_C_locale.free_instance (); -} -#endif - -static HB_LOCALE_T -get_C_locale () -{ - return static_C_locale.get_unconst (); -} -#endif /* USE_XLOCALE */ - -static bool -parse_float (const char **pp, const char *end, float *pv) -{ - char buf[32]; - unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); - strncpy (buf, *pp, len); - buf[len] = '\0'; - - char *p = buf; - char *pend = p; - float v; - - errno = 0; -#ifdef USE_XLOCALE - v = strtod_l (p, &pend, get_C_locale ()); -#else - v = strtod (p, &pend); -#endif - if (errno || p == pend) - return false; - - *pv = v; - *pp += pend - p; return true; } @@ -1099,7 +994,7 @@ static bool parse_variation_value (const char **pp, const char *end, hb_variation_t *variation) { parse_char (pp, end, '='); /* Optional. */ - return parse_float (pp, end, &variation->value); + return hb_parse_float (pp, end, &variation->value); } static bool diff --git a/src/hb-number.cc b/src/hb-number.cc new file mode 100644 index 000000000..d8291d96d --- /dev/null +++ b/src/hb-number.cc @@ -0,0 +1,138 @@ +/* + * Copyright © 2019 Ebrahim Byagowi + * + * 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 "hb-machinery.hh" +#include "hb-number.hh" + +#include +#ifdef HAVE_XLOCALE_H +#include +#endif + +bool +hb_parse_int (const char **pp, const char *end, int *pv) +{ + char buf[32]; + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + strncpy (buf, *pp, len); + buf[len] = '\0'; + + char *p = buf; + char *pend = p; + int v; + + errno = 0; + v = strtol (p, &pend, 10); + if (errno || p == pend) + return false; + + *pv = v; + *pp += pend - p; + return true; +} + +#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L) +#define USE_XLOCALE 1 +#define HB_LOCALE_T locale_t +#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr) +#define HB_FREE_LOCALE(loc) freelocale (loc) +#elif defined(_MSC_VER) +#define USE_XLOCALE 1 +#define HB_LOCALE_T _locale_t +#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName) +#define HB_FREE_LOCALE(loc) _free_locale (loc) +#define strtod_l(a, b, c) _strtod_l ((a), (b), (c)) +#endif + +#ifdef USE_XLOCALE + +#if HB_USE_ATEXIT +static void free_static_C_locale (); +#endif + +static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t, + hb_C_locale_lazy_loader_t> +{ + static HB_LOCALE_T create () + { + HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C"); + +#if HB_USE_ATEXIT + atexit (free_static_C_locale); +#endif + + return C_locale; + } + static void destroy (HB_LOCALE_T p) + { + HB_FREE_LOCALE (p); + } + static HB_LOCALE_T get_null () + { + return nullptr; + } +} static_C_locale; + +#if HB_USE_ATEXIT +static +void free_static_C_locale () +{ + static_C_locale.free_instance (); +} +#endif + +static HB_LOCALE_T +get_C_locale () +{ + return static_C_locale.get_unconst (); +} +#endif /* USE_XLOCALE */ + +bool +hb_parse_float (const char **pp, const char *end, float *pv) +{ + char buf[32]; + unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp)); + strncpy (buf, *pp, len); + buf[len] = '\0'; + + char *p = buf; + char *pend = p; + float v; + + errno = 0; +#ifdef USE_XLOCALE + v = strtod_l (p, &pend, get_C_locale ()); +#else + v = strtod (p, &pend); +#endif + if (errno || p == pend) + return false; + + *pv = v; + *pp += pend - p; + return true; +} diff --git a/src/hb-number.hh b/src/hb-number.hh new file mode 100644 index 000000000..54679a79c --- /dev/null +++ b/src/hb-number.hh @@ -0,0 +1,35 @@ +/* + * Copyright © 2019 Ebrahim Byagowi + * + * 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. + * + */ + +#ifndef HB_NUMBER_HH +#define HB_NUMBER_HH + +HB_INTERNAL bool +hb_parse_int (const char **pp, const char *end, int *pv); + +HB_INTERNAL bool +hb_parse_float (const char **pp, const char *end, float *pv); + +#endif /* HB_NUMBER_HH */