]> git.proxmox.com Git - grub2.git/blame - util/grub-gen-asciih.c
fs/ntfs: Fix various OOB reads and writes (CVE-2023-4692, CVE-2023-4693)
[grub2.git] / util / grub-gen-asciih.c
CommitLineData
c6b066f2
VS
1/*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2009,2010 Free Software Foundation, Inc.
4 *
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include <errno.h>
24
25#include <ft2build.h>
26#include FT_FREETYPE_H
27#include FT_TRUETYPE_TAGS_H
28#include FT_TRUETYPE_TABLES_H
fd0df6d0 29#include FT_SYNTHESIS_H
c6b066f2
VS
30
31#undef __FTERRORS_H__
32#define FT_ERROR_START_LIST const char *ft_errmsgs[] = {
33#define FT_ERRORDEF(e, v, s) [e] = s,
34#define FT_ERROR_END_LIST };
35#include FT_ERRORS_H
36
37#define GRUB_FONT_DEFAULT_SIZE 16
38
39#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
40
41struct grub_glyph_info
42{
43 int width;
44 int height;
45 int x_ofs;
46 int y_ofs;
47 int device_width;
48 int bitmap_size;
49 unsigned char *bitmap;
50};
51
52static void
53add_pixel (unsigned char **data, int *mask, int not_blank)
54{
55 if (*mask == 0)
56 {
57 (*data)++;
58 **data = 0;
59 *mask = 128;
60 }
61
62 if (not_blank)
63 **data |= *mask;
64
65 *mask >>= 1;
66}
67
68static void
69add_glyph (FT_UInt glyph_idx, FT_Face face,
70 unsigned int char_code,
71 struct grub_glyph_info *glyph_info)
72{
73 int width, height;
74 int cuttop, cutbottom, cutleft, cutright;
75 unsigned char *data;
76 int mask, i, j, bitmap_size;
77 FT_GlyphSlot glyph;
78 int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME;
79 FT_Error err;
80
81 err = FT_Load_Glyph (face, glyph_idx, flag);
82 if (err)
83 {
87de66d9 84 fprintf (stderr, "Freetype Error %d loading glyph 0x%x for U+0x%x",
c6b066f2
VS
85 err, glyph_idx, char_code);
86
87 if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs))
87de66d9 88 fprintf (stderr, ": %s\n", ft_errmsgs[err]);
c6b066f2 89 else
87de66d9
TW
90 fprintf (stderr, "\n");
91 exit (1);
c6b066f2
VS
92 }
93
94 glyph = face->glyph;
95
96 if (glyph->next)
97 printf ("%x\n", char_code);
98
99 cuttop = cutbottom = cutleft = cutright = 0;
100
101 width = glyph->bitmap.width;
102 height = glyph->bitmap.rows;
103
104 bitmap_size = ((width * height + 7) / 8);
105 glyph_info->bitmap = malloc (bitmap_size);
106 if (!glyph_info->bitmap)
107 {
108 fprintf (stderr, "grub-gen-asciih: error: out of memory");
109 exit (1);
110 }
111 glyph_info->bitmap_size = bitmap_size;
112
113 glyph_info->width = width;
114 glyph_info->height = height;
115 glyph_info->x_ofs = glyph->bitmap_left;
116 glyph_info->y_ofs = glyph->bitmap_top - height;
117 glyph_info->device_width = glyph->metrics.horiAdvance / 64;
118
119 mask = 0;
120 data = &glyph_info->bitmap[0] - 1;
121 for (j = cuttop; j < height + cuttop; j++)
122 for (i = cutleft; i < width + cutleft; i++)
123 add_pixel (&data, &mask,
124 glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] &
125 (1 << (7 - (i & 7))));
126}
127
128static void
129write_font_ascii_bitmap (FILE *file, FT_Face face)
130{
c6b066f2
VS
131 int char_code;
132
133 fprintf (file, "/* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */\n");
134 fprintf (file, "unsigned char ascii_bitmaps[] =\n");
135 fprintf (file, "{\n");
136
137 for (char_code = 0; char_code <= 0x7f; char_code++)
138 {
139 FT_UInt glyph_idx;
87de66d9
TW
140 struct grub_glyph_info glyph;
141
c6b066f2
VS
142 glyph_idx = FT_Get_Char_Index (face, char_code);
143 if (!glyph_idx)
144 return;
87de66d9
TW
145
146 memset (&glyph, 0, sizeof(glyph));
147
c6b066f2
VS
148 add_glyph (glyph_idx, face, char_code, &glyph);
149
150 if (glyph.width == 8 && glyph.height == 16
151 && glyph.x_ofs == 0 && glyph.y_ofs == 0)
152 {
153 int row;
154 for (row = 0; row < 16; row++)
155 fprintf (file, "0x%02x, ", glyph.bitmap[row]);
156 }
157 else
158 {
159 unsigned char glph[16];
160 int p = 0, mask = 0x80;
161 int row, col;
162 int dy = 12 - glyph.height - glyph.y_ofs;
163 for (row = 0; row < 16; row++)
164 glph[row] = 0;
165 for (row = 0; row < glyph.height; row++)
166 for (col = 0; col < glyph.width; col++)
167 {
168 int val = glyph.bitmap[p] & mask;
169 mask >>= 1;
170 if (mask == 0)
171 {
172 mask = 0x80;
173 p++;
174 }
175 if (val && dy + row >= 0
176 && dy + row < 16
177 && glyph.x_ofs + col >= 0
178 && glyph.x_ofs + col < 8)
179 glph[dy + row] |= 1 << (7 - (glyph.x_ofs + col));
180 }
181 for (row = 0; row < 16; row++)
182 fprintf (file, "0x%02x, ", glph[row]);
183 }
184 fprintf (file, "\n");
185 free (glyph.bitmap);
186 }
187 fprintf (file, "};\n");
188}
189
190int
191main (int argc, char *argv[])
192{
193 FT_Library ft_lib;
194 FT_Face ft_face;
195 FILE *file;
196
197 if (argc != 3)
198 {
199 fprintf (stderr, "grub-gen-asciih: usage: INPUT OUTPUT");
200 return 1;
201 }
202
203 if (FT_Init_FreeType (&ft_lib))
204 {
205 fprintf (stderr, "grub-gen-asciih: error: FT_Init_FreeType fails");
206 return 1;
207 }
208
209 {
210 int size;
211 FT_Error err;
212
213 err = FT_New_Face (ft_lib, argv[1], 0, &ft_face);
214 if (err)
215 {
216 fprintf (stderr, "can't open file %s, index %d: error %d",
217 argv[1], 0, err);
218 if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs))
219 fprintf (stderr, ": %s\n", ft_errmsgs[err]);
220 else
221 fprintf (stderr, "\n");
222
223 return 1;
224 }
225
226 if ((ft_face->face_flags & FT_FACE_FLAG_SCALABLE) ||
227 (! ft_face->num_fixed_sizes))
228 size = GRUB_FONT_DEFAULT_SIZE;
229 else
230 size = ft_face->available_sizes[0].height;
231
232 if (FT_Set_Pixel_Sizes (ft_face, size, size))
233 {
234 fprintf (stderr, "grub-gen-asciih: error: can't set %dx%d font size", size, size);
235 return 1;
236 }
237 }
238
239 file = fopen (argv[2], "w");
240 if (! file)
241 {
242 fprintf (stderr, "grub-gen-asciih: error: cannot write to `%s': %s", argv[2],
243 strerror (errno));
244 return 1;
245 }
246
247 write_font_ascii_bitmap (file, ft_face);
248
249 fclose (file);
250
251 FT_Done_Face (ft_face);
252
253 FT_Done_FreeType (ft_lib);
254
255 return 0;
256}