Coverage Report

Created: 2023-06-07 06:14

/src/harfbuzz/src/hb-cff-interp-dict-common.hh
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright © 2018 Adobe Inc.
3
 *
4
 *  This is part of HarfBuzz, a text shaping library.
5
 *
6
 * Permission is hereby granted, without written agreement and without
7
 * license or royalty fees, to use, copy, modify, and distribute this
8
 * software and its documentation for any purpose, provided that the
9
 * above copyright notice and the following two paragraphs appear in
10
 * all copies of this software.
11
 *
12
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16
 * DAMAGE.
17
 *
18
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23
 *
24
 * Adobe Author(s): Michiharu Ariza
25
 */
26
#ifndef HB_CFF_INTERP_DICT_COMMON_HH
27
#define HB_CFF_INTERP_DICT_COMMON_HH
28
29
#include "hb-cff-interp-common.hh"
30
31
namespace CFF {
32
33
using namespace OT;
34
35
/* an opstr and the parsed out dict value(s) */
36
struct dict_val_t : op_str_t
37
{
38
0
  void init () {}
39
0
  void fini () {}
40
};
41
42
typedef dict_val_t num_dict_val_t;
43
44
template <typename VAL> struct dict_values_t : parsed_values_t<VAL> {};
45
46
template <typename OPSTR=op_str_t>
47
struct top_dict_values_t : dict_values_t<OPSTR>
48
{
49
  void init ()
50
0
  {
51
0
    dict_values_t<OPSTR>::init ();
52
0
    charStringsOffset = 0;
53
0
    FDArrayOffset = 0;
54
0
  }
Unexecuted instantiation: CFF::top_dict_values_t<CFF::cff1_top_dict_val_t>::init()
Unexecuted instantiation: CFF::top_dict_values_t<CFF::op_str_t>::init()
55
0
  void fini () { dict_values_t<OPSTR>::fini (); }
Unexecuted instantiation: CFF::top_dict_values_t<CFF::cff1_top_dict_val_t>::fini()
Unexecuted instantiation: CFF::top_dict_values_t<CFF::op_str_t>::fini()
56
57
  unsigned int  charStringsOffset;
58
  unsigned int  FDArrayOffset;
59
};
60
61
struct dict_opset_t : opset_t<number_t>
62
{
63
  static void process_op (op_code_t op, interp_env_t<number_t>& env)
64
0
  {
65
0
    switch (op) {
66
0
      case OpCode_longintdict:  /* 5-byte integer */
67
0
  env.argStack.push_longint_from_substr (env.str_ref);
68
0
  break;
69
70
0
      case OpCode_BCD:  /* real number */
71
0
  env.argStack.push_real (parse_bcd (env.str_ref));
72
0
  break;
73
74
0
      default:
75
0
  opset_t<number_t>::process_op (op, env);
76
0
  break;
77
0
    }
78
0
  }
79
80
  /* Turns CFF's BCD format into strtod understandable string */
81
  static double parse_bcd (byte_str_ref_t& str_ref)
82
0
  {
83
0
    if (unlikely (str_ref.in_error ())) return .0;
84
85
0
    enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
86
87
0
    char buf[32];
88
0
    unsigned char byte = 0;
89
0
    for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count)
90
0
    {
91
0
      unsigned nibble;
92
0
      if (!(i & 1))
93
0
      {
94
0
  if (unlikely (!str_ref.avail ())) break;
95
96
0
  byte = str_ref[0];
97
0
  str_ref.inc ();
98
0
  nibble = byte >> 4;
99
0
      }
100
0
      else
101
0
  nibble = byte & 0x0F;
102
103
0
      if (unlikely (nibble == RESERVED)) break;
104
0
      else if (nibble == END)
105
0
      {
106
0
  const char *p = buf;
107
0
  double pv;
108
0
  if (unlikely (!hb_parse_double (&p, p + count, &pv, true/* whole buffer */)))
109
0
    break;
110
0
  return pv;
111
0
      }
112
0
      else
113
0
      {
114
0
  buf[count] = "0123456789.EE?-?"[nibble];
115
0
  if (nibble == EXP_NEG)
116
0
  {
117
0
    ++count;
118
0
    if (unlikely (count == ARRAY_LENGTH (buf))) break;
119
0
    buf[count] = '-';
120
0
  }
121
0
      }
122
0
    }
123
124
0
    str_ref.set_error ();
125
0
    return .0;
126
0
  }
127
128
  static bool is_hint_op (op_code_t op)
129
0
  {
130
0
    switch (op)
131
0
    {
132
0
      case OpCode_BlueValues:
133
0
      case OpCode_OtherBlues:
134
0
      case OpCode_FamilyBlues:
135
0
      case OpCode_FamilyOtherBlues:
136
0
      case OpCode_StemSnapH:
137
0
      case OpCode_StemSnapV:
138
0
      case OpCode_StdHW:
139
0
      case OpCode_StdVW:
140
0
      case OpCode_BlueScale:
141
0
      case OpCode_BlueShift:
142
0
      case OpCode_BlueFuzz:
143
0
      case OpCode_ForceBold:
144
0
      case OpCode_LanguageGroup:
145
0
      case OpCode_ExpansionFactor:
146
0
  return true;
147
0
      default:
148
0
  return false;
149
0
    }
150
0
  }
151
};
152
153
template <typename VAL=op_str_t>
154
struct top_dict_opset_t : dict_opset_t
155
{
156
  static void process_op (op_code_t op, interp_env_t<number_t>& env, top_dict_values_t<VAL> & dictval)
157
0
  {
158
0
    switch (op) {
159
0
      case OpCode_CharStrings:
160
0
  dictval.charStringsOffset = env.argStack.pop_uint ();
161
0
  env.clear_args ();
162
0
  break;
163
0
      case OpCode_FDArray:
164
0
  dictval.FDArrayOffset = env.argStack.pop_uint ();
165
0
  env.clear_args ();
166
0
  break;
167
0
      case OpCode_FontMatrix:
168
0
  env.clear_args ();
169
0
  break;
170
0
      default:
171
0
  dict_opset_t::process_op (op, env);
172
0
  break;
173
0
    }
174
0
  }
Unexecuted instantiation: CFF::top_dict_opset_t<CFF::cff1_top_dict_val_t>::process_op(unsigned int, CFF::interp_env_t<CFF::number_t>&, CFF::top_dict_values_t<CFF::cff1_top_dict_val_t>&)
Unexecuted instantiation: CFF::top_dict_opset_t<CFF::op_str_t>::process_op(unsigned int, CFF::interp_env_t<CFF::number_t>&, CFF::top_dict_values_t<CFF::op_str_t>&)
175
};
176
177
template <typename OPSET, typename PARAM, typename ENV=num_interp_env_t>
178
struct dict_interpreter_t : interpreter_t<ENV>
179
{
180
0
  dict_interpreter_t (ENV& env_) : interpreter_t<ENV> (env_) {}
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff1_top_dict_opset_t, CFF::cff1_top_dict_values_t, CFF::cff1_top_dict_interp_env_t>::dict_interpreter_t(CFF::cff1_top_dict_interp_env_t&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff1_font_dict_opset_t, CFF::cff1_font_dict_values_t, CFF::interp_env_t<CFF::number_t> >::dict_interpreter_t(CFF::interp_env_t<CFF::number_t>&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff1_private_dict_opset_t, CFF::cff1_private_dict_values_base_t<CFF::dict_val_t>, CFF::interp_env_t<CFF::number_t> >::dict_interpreter_t(CFF::interp_env_t<CFF::number_t>&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff2_top_dict_opset_t, CFF::cff2_top_dict_values_t, CFF::interp_env_t<CFF::number_t> >::dict_interpreter_t(CFF::interp_env_t<CFF::number_t>&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff2_font_dict_opset_t, CFF::cff2_font_dict_values_t, CFF::interp_env_t<CFF::number_t> >::dict_interpreter_t(CFF::interp_env_t<CFF::number_t>&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff2_private_dict_opset_t, CFF::cff2_private_dict_values_base_t<CFF::dict_val_t>, CFF::cff2_priv_dict_interp_env_t>::dict_interpreter_t(CFF::cff2_priv_dict_interp_env_t&)
181
182
  bool interpret (PARAM& param)
183
0
  {
184
0
    param.init ();
185
0
    while (SUPER::env.str_ref.avail ())
186
0
    {
187
0
      OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
188
0
      if (unlikely (SUPER::env.in_error ()))
189
0
  return false;
190
0
    }
191
192
0
    return true;
193
0
  }
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff1_top_dict_opset_t, CFF::cff1_top_dict_values_t, CFF::cff1_top_dict_interp_env_t>::interpret(CFF::cff1_top_dict_values_t&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff1_font_dict_opset_t, CFF::cff1_font_dict_values_t, CFF::interp_env_t<CFF::number_t> >::interpret(CFF::cff1_font_dict_values_t&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff1_private_dict_opset_t, CFF::cff1_private_dict_values_base_t<CFF::dict_val_t>, CFF::interp_env_t<CFF::number_t> >::interpret(CFF::cff1_private_dict_values_base_t<CFF::dict_val_t>&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff2_top_dict_opset_t, CFF::cff2_top_dict_values_t, CFF::interp_env_t<CFF::number_t> >::interpret(CFF::cff2_top_dict_values_t&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff2_font_dict_opset_t, CFF::cff2_font_dict_values_t, CFF::interp_env_t<CFF::number_t> >::interpret(CFF::cff2_font_dict_values_t&)
Unexecuted instantiation: CFF::dict_interpreter_t<CFF::cff2_private_dict_opset_t, CFF::cff2_private_dict_values_base_t<CFF::dict_val_t>, CFF::cff2_priv_dict_interp_env_t>::interpret(CFF::cff2_private_dict_values_base_t<CFF::dict_val_t>&)
194
195
  private:
196
  typedef interpreter_t<ENV> SUPER;
197
};
198
199
} /* namespace CFF */
200
201
#endif /* HB_CFF_INTERP_DICT_COMMON_HH */