summaryrefslogtreecommitdiffstats
path: root/meta/recipes-graphics/harfbuzz/harfbuzz/CVE-2023-25193-pre0.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-graphics/harfbuzz/harfbuzz/CVE-2023-25193-pre0.patch')
-rw-r--r--meta/recipes-graphics/harfbuzz/harfbuzz/CVE-2023-25193-pre0.patch335
1 files changed, 335 insertions, 0 deletions
diff --git a/meta/recipes-graphics/harfbuzz/harfbuzz/CVE-2023-25193-pre0.patch b/meta/recipes-graphics/harfbuzz/harfbuzz/CVE-2023-25193-pre0.patch
new file mode 100644
index 0000000000..90d4cfefb4
--- /dev/null
+++ b/meta/recipes-graphics/harfbuzz/harfbuzz/CVE-2023-25193-pre0.patch
@@ -0,0 +1,335 @@
1From 3122c2cdc45a964efedad8953a2df67205c3e3a8 Mon Sep 17 00:00:00 2001
2From: Behdad Esfahbod <behdad@behdad.org>
3Date: Sat, 4 Dec 2021 19:50:33 -0800
4Subject: [PATCH] [buffer] Add HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
5
6Fixes https://github.com/harfbuzz/harfbuzz/issues/1463
7Upstream-Status: Backport from [https://github.com/harfbuzz/harfbuzz/commit/3122c2cdc45a964efedad8953a2df67205c3e3a8]
8Comment1: To backport the fix for CVE-2023-25193, add defination for HB_GLYPH_FLAG_UNSAFE_TO_CONCAT. This patch is needed along with CVE-2023-25193-pre1.patch for sucessfull porting.
9Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
10---
11 src/hb-buffer.cc | 10 ++---
12 src/hb-buffer.h | 76 ++++++++++++++++++++++++++++++------
13 src/hb-buffer.hh | 33 ++++++++++------
14 src/hb-ot-layout-gsubgpos.hh | 39 +++++++++++++++---
15 src/hb-ot-shape.cc | 8 +---
16 5 files changed, 124 insertions(+), 42 deletions(-)
17
18diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
19index 6131c86..bba5eae 100644
20--- a/src/hb-buffer.cc
21+++ b/src/hb-buffer.cc
22@@ -610,14 +610,14 @@ done:
23 }
24
25 void
26-hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
27+hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end, hb_mask_t mask)
28 {
29 unsigned int cluster = (unsigned int) -1;
30 cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster);
31- _unsafe_to_break_set_mask (info, start, end, cluster);
32+ _unsafe_to_break_set_mask (info, start, end, cluster, mask);
33 }
34 void
35-hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
36+hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end, hb_mask_t mask)
37 {
38 if (!have_output)
39 {
40@@ -631,8 +631,8 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en
41 unsigned int cluster = (unsigned int) -1;
42 cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster);
43 cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster);
44- _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
45- _unsafe_to_break_set_mask (info, idx, end, cluster);
46+ _unsafe_to_break_set_mask (out_info, start, out_len, cluster, mask);
47+ _unsafe_to_break_set_mask (info, idx, end, cluster, mask);
48 }
49
50 void
51diff --git a/src/hb-buffer.h b/src/hb-buffer.h
52index d5cb746..42dc92a 100644
53--- a/src/hb-buffer.h
54+++ b/src/hb-buffer.h
55@@ -77,26 +77,76 @@ typedef struct hb_glyph_info_t
56 * @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the
57 * beginning of the cluster this glyph is part of,
58 * then both sides need to be re-shaped, as the
59- * result might be different. On the flip side,
60- * it means that when this flag is not present,
61- * then it's safe to break the glyph-run at the
62- * beginning of this cluster, and the two sides
63- * represent the exact same result one would get
64- * if breaking input text at the beginning of
65- * this cluster and shaping the two sides
66- * separately. This can be used to optimize
67- * paragraph layout, by avoiding re-shaping
68- * of each line after line-breaking, or limiting
69- * the reshaping to a small piece around the
70- * breaking point only.
71+ * result might be different.
72+ *
73+ * On the flip side, it means that when this
74+ * flag is not present, then it is safe to break
75+ * the glyph-run at the beginning of this
76+ * cluster, and the two sides will represent the
77+ * exact same result one would get if breaking
78+ * input text at the beginning of this cluster
79+ * and shaping the two sides separately.
80+ *
81+ * This can be used to optimize paragraph
82+ * layout, by avoiding re-shaping of each line
83+ * after line-breaking.
84+ *
85+ * @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT: Indicates that if input text is changed on one
86+ * side of the beginning of the cluster this glyph
87+ * is part of, then the shaping results for the
88+ * other side might change.
89+ *
90+ * Note that the absence of this flag will NOT by
91+ * itself mean that it IS safe to concat text.
92+ * Only two pieces of text both of which clear of
93+ * this flag can be concatenated safely.
94+ *
95+ * This can be used to optimize paragraph
96+ * layout, by avoiding re-shaping of each line
97+ * after line-breaking, by limiting the
98+ * reshaping to a small piece around the
99+ * breaking positin only, even if the breaking
100+ * position carries the
101+ * #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
102+ * hyphenation or other text transformation
103+ * happens at line-break position, in the following
104+ * way:
105+ *
106+ * 1. Iterate back from the line-break position till
107+ * the the first cluster start position that is
108+ * NOT unsafe-to-concat, 2. shape the segment from
109+ * there till the end of line, 3. check whether the
110+ * resulting glyph-run also is clear of the
111+ * unsafe-to-concat at its start-of-text position;
112+ * if it is, just splice it into place and the line
113+ * is shaped; If not, move on to a position further
114+ * back that is clear of unsafe-to-concat and retry
115+ * from there, and repeat.
116+ *
117+ * At the start of next line a similar algorithm can
118+ * be implemented. A slight complication will arise,
119+ * because while our buffer API has a way to
120+ * return flags for position corresponding to
121+ * start-of-text, there is currently no position
122+ * corresponding to end-of-text. This limitation
123+ * can be alleviated by shaping more text than needed
124+ * and looking for unsafe-to-concat flag within text
125+ * clusters.
126+ *
127+ * The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
128+ * always imply this flag.
129+ *
130+ * Since: REPLACEME
131+ *
132 * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
133 *
134 * Since: 1.5.0
135 */
136 typedef enum { /*< flags >*/
137 HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
138+ HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002,
139
140- HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */
141+ HB_GLYPH_FLAG_DEFINED = 0x00000003 /* OR of all defined flags */
142 } hb_glyph_flags_t;
143
144 HB_EXTERN hb_glyph_flags_t
145diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh
146index b5596d9..beac7b6 100644
147--- a/src/hb-buffer.hh
148+++ b/src/hb-buffer.hh
149@@ -67,8 +67,8 @@ enum hb_buffer_scratch_flags_t {
150 HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u,
151 HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
152 HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
153- HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
154- HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u,
155+ HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u,
156+ HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u,
157
158 /* Reserved for complex shapers' internal use. */
159 HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
160@@ -324,8 +324,19 @@ struct hb_buffer_t
161 return;
162 unsafe_to_break_impl (start, end);
163 }
164- HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end);
165- HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end);
166+ void unsafe_to_concat (unsigned int start,
167+ unsigned int end)
168+ {
169+ if (end - start < 2)
170+ return;
171+ unsafe_to_break_impl (start, end, HB_GLYPH_FLAG_UNSAFE_TO_CONCAT);
172+ }
173+ HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end,
174+ hb_mask_t mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT);
175+ HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end,
176+ hb_mask_t mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT);
177+ void unsafe_to_concat_from_outbuffer (unsigned int start, unsigned int end)
178+ { unsafe_to_break_from_outbuffer (start, end, HB_GLYPH_FLAG_UNSAFE_TO_CONCAT); }
179
180
181 /* Internal methods */
182@@ -377,12 +388,7 @@ struct hb_buffer_t
183 set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
184 {
185 if (inf.cluster != cluster)
186- {
187- if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
188- inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
189- else
190- inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
191- }
192+ inf.mask = (inf.mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
193 inf.cluster = cluster;
194 }
195
196@@ -398,13 +404,14 @@ struct hb_buffer_t
197 void
198 _unsafe_to_break_set_mask (hb_glyph_info_t *infos,
199 unsigned int start, unsigned int end,
200- unsigned int cluster)
201+ unsigned int cluster,
202+ hb_mask_t mask)
203 {
204 for (unsigned int i = start; i < end; i++)
205 if (cluster != infos[i].cluster)
206 {
207- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
208- infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
209+ scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
210+ infos[i].mask |= mask;
211 }
212 }
213
214diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
215index 579d178..a6ca456 100644
216--- a/src/hb-ot-layout-gsubgpos.hh
217+++ b/src/hb-ot-layout-gsubgpos.hh
218@@ -369,7 +369,7 @@ struct hb_ot_apply_context_t :
219 may_skip (const hb_glyph_info_t &info) const
220 { return matcher.may_skip (c, info); }
221
222- bool next ()
223+ bool next (unsigned *unsafe_to = nullptr)
224 {
225 assert (num_items > 0);
226 while (idx + num_items < end)
227@@ -392,11 +392,17 @@ struct hb_ot_apply_context_t :
228 }
229
230 if (skip == matcher_t::SKIP_NO)
231+ {
232+ if (unsafe_to)
233+ *unsafe_to = idx + 1;
234 return false;
235+ }
236 }
237+ if (unsafe_to)
238+ *unsafe_to = end;
239 return false;
240 }
241- bool prev ()
242+ bool prev (unsigned *unsafe_from = nullptr)
243 {
244 assert (num_items > 0);
245 while (idx > num_items - 1)
246@@ -419,8 +425,14 @@ struct hb_ot_apply_context_t :
247 }
248
249 if (skip == matcher_t::SKIP_NO)
250+ {
251+ if (unsafe_from)
252+ *unsafe_from = hb_max (1u, idx) - 1u;
253 return false;
254+ }
255 }
256+ if (unsafe_from)
257+ *unsafe_from = 0;
258 return false;
259 }
260
261@@ -834,7 +846,12 @@ static inline bool match_input (hb_ot_apply_context_t *c,
262 match_positions[0] = buffer->idx;
263 for (unsigned int i = 1; i < count; i++)
264 {
265- if (!skippy_iter.next ()) return_trace (false);
266+ unsigned unsafe_to;
267+ if (!skippy_iter.next (&unsafe_to))
268+ {
269+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
270+ return_trace (false);
271+ }
272
273 match_positions[i] = skippy_iter.idx;
274
275@@ -1022,8 +1039,14 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c,
276 skippy_iter.set_match_func (match_func, match_data, backtrack);
277
278 for (unsigned int i = 0; i < count; i++)
279- if (!skippy_iter.prev ())
280+ {
281+ unsigned unsafe_from;
282+ if (!skippy_iter.prev (&unsafe_from))
283+ {
284+ c->buffer->unsafe_to_concat_from_outbuffer (unsafe_from, c->buffer->idx);
285 return_trace (false);
286+ }
287+ }
288
289 *match_start = skippy_iter.idx;
290
291@@ -1045,8 +1068,14 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
292 skippy_iter.set_match_func (match_func, match_data, lookahead);
293
294 for (unsigned int i = 0; i < count; i++)
295- if (!skippy_iter.next ())
296+ {
297+ unsigned unsafe_to;
298+ if (!skippy_iter.next (&unsafe_to))
299+ {
300+ c->buffer->unsafe_to_concat (c->buffer->idx + offset, unsafe_to);
301 return_trace (false);
302+ }
303+ }
304
305 *end_index = skippy_iter.idx + 1;
306
307diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
308index 5d9a70c..5d10b30 100644
309--- a/src/hb-ot-shape.cc
310+++ b/src/hb-ot-shape.cc
311@@ -1008,7 +1008,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
312 /* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
313 * Simplifies using them. */
314
315- if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
316+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS))
317 return;
318
319 hb_glyph_info_t *info = buffer->info;
320@@ -1017,11 +1017,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
321 {
322 unsigned int mask = 0;
323 for (unsigned int i = start; i < end; i++)
324- if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
325- {
326- mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
327- break;
328- }
329+ mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED;
330 if (mask)
331 for (unsigned int i = start; i < end; i++)
332 info[i].mask |= mask;
333--
3342.25.1
335