I have found an error scenario that leads to an infinite printing loop
chenwj <[email protected]> Thu, 29 Aug 2024 15:54:38 +0800 (CST)
| Newsgroups | gmane.comp.boot-loaders.grub.bugs |
|---|---|
| Message-ID | <[email protected]> |
Hi, I have found an error scenario that leads to an infinite printing loop. This scenario requires the following two commands to be present in grub.cfg: "set lang=zh_CN" and "terminal_output gfxterm", and it must also be retrieved through PXE. Attached is the patch to fix the issue. Thank you for your attention, and I look forward to your response. You can reach me through this email. Chen Weijie Tel: 18362375558
0001-term-Fix-the-calculation-on-character-width-when-set.patch
(application/octet-stream, 3.1 KB)
From f415f038198cee6fcd9d16d228b85a6095a5c92f Mon Sep 17 00:00:00 2001 From: Chen Weijie <[email protected]> Date: Mon, 5 Aug 2024 14:11:37 +0800 Subject: [PATCH] term: Fix the calculation on character width when setting LANG="zh_CN" Under an environment with the simplified Chinese language support, BIOS enables the PXE module to load GRUB bootstrap files, it will invoke the grub_normal_parse_line() function to parse and execute the grub.cfg file. The recursive error printing occurs as follows: > ?????????cannot allocate pages??? > ?????????cannot allocate pages??? > ?????????cannot allocate pages??? The reason is that when GRUB executes the command "terminal_output gfxterm" to set the terminal type, the width of characters cannot be correctly calculated in calculate_normal_character_width() due to the lack of consideration for simplified Chinese encoding support. This leads to a recursive loop printing error behavior after GRUB calls the grub_print_error() API function. This commit adds the simplified Chinese support, fixes character calculation, and resolves this issue. Signed-off-by: Chen Weijie <[email protected]> Signed-off-by: Su Weiqiang <[email protected]> Signed-off-by: Zhao Yihan <[email protected]> --- grub-core/term/gfxterm.c | 43 +++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 3c468f459..1fb637de1 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -936,26 +936,45 @@ grub_gfxterm_putchar (struct grub_term_output *term, draw_cursor (1); } -/* Use ASCII characters to determine normal character width. */ +/* Iterate character width */ static unsigned int -calculate_normal_character_width (grub_font_t font) +iterate_character_width (grub_font_t font, unsigned int width, unsigned int start, unsigned int end) { struct grub_font_glyph *glyph; - unsigned int width = 0; unsigned int i; + for (i = start; i < end; i++) { + glyph = grub_font_get_glyph (font, i); + + if (!glyph) + continue; + + if (glyph->device_width > width) + width = glyph->device_width; + } + + return width; +} + +/* Use ASCII characters or simplified Chinese characters to determine + * normal character width. */ +static unsigned int +calculate_normal_character_width (grub_font_t font) +{ + unsigned int width = 0; + const char *lang_name; + /* Get properties of every printable ASCII character. */ - for (i = 32; i < 127; i++) - { - glyph = grub_font_get_glyph (font, i); + lang_name = grub_env_get ("lang"); - /* Skip unknown characters. Should never happen on normal conditions. */ - if (! glyph) - continue; + if (!grub_strcmp (lang_name, "zh_CN")) { + width = iterate_character_width (font, width, 0x3000, 0x3002); + width = iterate_character_width (font, width, 0x4E00, 0x9FFF); + width = iterate_character_width (font, width, 0xFF00, 0xFFEF); + } + + width = iterate_character_width (font, width, 32, 127); - if (glyph->device_width > width) - width = glyph->device_width; - } if (!width) return 8; -- 2.24.3 (Apple Git-128)