diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh index aa2a1b95b..f2ccc2bdd 100644 --- a/src/hb-cff-interp-common.hh +++ b/src/hb-cff-interp-common.hh @@ -218,80 +218,41 @@ inline unsigned int OpCode_Size (OpCode op) { return Is_OpCode_ESC (op) ? 2: 1; struct Number { inline void init (void) - { set_int (0); } + { set_real (0.0); } inline void fini (void) {} - inline void set_int (int v) { format = NumInt; u.int_val = v; } - inline int to_int (void) const { return is_int ()? u.int_val: (int)to_real (); } - inline void set_fixed (int32_t v) { format = NumFixed; u.fixed_val = v; } + inline void set_int (int v) { value = (double)v; } + inline int to_int (void) const { return (int)value; } + inline void set_fixed (int32_t v) { value = v / 65536.0; } inline int32_t to_fixed (void) const { - if (is_fixed ()) - return u.fixed_val; - else if (is_real ()) - return (int32_t)(u.real_val * 65536.0f); - else - return (int32_t)(u.int_val << 16); + return (int32_t)(value * 65536.0); } - inline void set_real (float v) { format = NumReal; u.real_val = v; } - inline float to_real (void) const + inline void set_real (double v) { value = v; } + inline double to_real (void) const { - if (is_real ()) - return u.real_val; - if (is_fixed ()) - return u.fixed_val / 65536.0f; - else - return (float)u.int_val; + return value; } inline int ceil (void) const { - switch (format) - { - default: - case NumInt: - return u.int_val; - case NumFixed: - return (u.fixed_val + 0xFFFF) >> 16; - case NumReal: - return (int)ceilf (u.real_val); - } + return (int)::ceil (value); } inline int floor (void) const { - switch (format) - { - default: - case NumInt: - return u.int_val; - case NumFixed: - return u.fixed_val >> 16; - case NumReal: - return (int)floorf (u.real_val); - } + return (int)::floor (value); } inline bool in_int_range (void) const { - if (is_int ()) - return true; - if (is_fixed () && ((u.fixed_val & 0xFFFF) == 0)) - return true; - else - return ((float)(int16_t)to_int () == u.real_val); + return ((double)(int16_t)to_int () == value); } inline bool operator > (const Number &n) const { - switch (format) - { - default: - case NumInt: return u.int_val > n.to_int (); - case NumFixed: return u.fixed_val > n.to_fixed (); - case NumReal: return u.real_val > n.to_real (); - } + return value > n.to_real (); } inline bool operator < (const Number &n) const @@ -305,32 +266,13 @@ struct Number inline const Number &operator += (const Number &n) { - if (format == NumReal || n.format == NumReal) - set_real (to_real () + n.to_real ()); - else if (format == NumFixed || n.format == NumFixed) - set_fixed (to_fixed () + n.to_fixed ()); - else - set_int (to_int () + n.to_int ()); + set_real (to_real () + n.to_real ()); return *this; } protected: - enum NumFormat { - NumInt, - NumFixed, - NumReal - }; - NumFormat format; - union { - int int_val; - int32_t fixed_val; - float real_val; - } u; - - inline bool is_int (void) const { return format == NumInt; } - inline bool is_fixed (void) const { return format == NumFixed; } - inline bool is_real (void) const { return format == NumReal; } + double value; }; /* byte string */ @@ -578,7 +520,7 @@ struct ArgStack : Stack n.set_fixed (v); } - inline void push_real (float v) + inline void push_real (double v) { ARG &n = S::push (); n.set_real (v); diff --git a/src/hb-cff-interp-dict-common.hh b/src/hb-cff-interp-dict-common.hh index aff356259..2822af40c 100644 --- a/src/hb-cff-interp-dict-common.hh +++ b/src/hb-cff-interp-dict-common.hh @@ -103,9 +103,9 @@ struct DictOpSet : OpSet } } - static inline float parse_bcd (SubByteStr& substr) + static inline double parse_bcd (SubByteStr& substr) { - float v = 0.0f; + double v = 0.0; bool neg = false; double int_part = 0; @@ -126,7 +126,7 @@ struct DictOpSet : OpSet if (!substr.avail ()) { substr.set_error (); - return 0.0f; + return 0.0; } byte = substr[0]; substr.inc (); @@ -152,13 +152,13 @@ struct DictOpSet : OpSet else value *= pow (10.0, (double)exp_part); } - return (float)value; + return value; case NEG: if (i != 0) { substr.set_error (); - return 0.0f; + return 0.0; } neg = true; break; diff --git a/src/hb-cff2-interp-cs.hh b/src/hb-cff2-interp-cs.hh index 8d193d621..d258b8148 100644 --- a/src/hb-cff2-interp-cs.hh +++ b/src/hb-cff2-interp-cs.hh @@ -49,7 +49,7 @@ struct BlendArg : Number inline void set_int (int v) { reset_blends (); Number::set_int (v); } inline void set_fixed (int32_t v) { reset_blends (); Number::set_fixed (v); } - inline void set_real (float v) { reset_blends (); Number::set_real (v); } + inline void set_real (double v) { reset_blends (); Number::set_real (v); } inline void set_blends (unsigned int numValues_, unsigned int valueIndex_, unsigned int numBlends, const BlendArg *blends_) @@ -169,10 +169,10 @@ struct CFF2CSInterpEnv : CSInterpEnv { if (likely (scalars.len == arg.deltas.len)) { - float v = arg.to_real (); + double v = arg.to_real (); for (unsigned int i = 0; i < scalars.len; i++) { - v += scalars[i] * arg.deltas[i].to_real (); + v += (double)scalars[i] * arg.deltas[i].to_real (); } arg.set_real (v); arg.deltas.resize (0); diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5647267827023872 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5647267827023872 new file mode 100644 index 000000000..068e7e8f7 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5647267827023872 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5725855502827520 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5725855502827520 new file mode 100644 index 000000000..5781bbad8 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5725855502827520 differ diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5736657639178240 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5736657639178240 new file mode 100644 index 000000000..343429cfa Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5736657639178240 differ