diff options
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.patch | 335 |
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 @@ | |||
1 | From 3122c2cdc45a964efedad8953a2df67205c3e3a8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Behdad Esfahbod <behdad@behdad.org> | ||
3 | Date: Sat, 4 Dec 2021 19:50:33 -0800 | ||
4 | Subject: [PATCH] [buffer] Add HB_GLYPH_FLAG_UNSAFE_TO_CONCAT | ||
5 | |||
6 | Fixes https://github.com/harfbuzz/harfbuzz/issues/1463 | ||
7 | Upstream-Status: Backport from [https://github.com/harfbuzz/harfbuzz/commit/3122c2cdc45a964efedad8953a2df67205c3e3a8] | ||
8 | Comment1: 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. | ||
9 | Signed-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 | |||
18 | diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc | ||
19 | index 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 | ||
51 | diff --git a/src/hb-buffer.h b/src/hb-buffer.h | ||
52 | index 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 | ||
145 | diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh | ||
146 | index 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 | |||
214 | diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh | ||
215 | index 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 | |||
307 | diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc | ||
308 | index 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 | -- | ||
334 | 2.25.1 | ||
335 | |||