[uClibc] (mconf SEGV) cols/COLS and rows/LINES inconsistency
ikaruga at cyberspace.org
ikaruga at cyberspace.org
Mon Sep 15 15:16:32 UTC 2003
(using uClibc source from uClibc-20030910.tar.bz2 and libncurses-5.3)
The mconf.c uses global variables COLS and ROWS from libncurses, and values
obtained by TIOCGWINSZ ioctl independently. They can get unsynchronized, example
libncurses is configured to not detect number of terminal rows and columns
via ioctl (disable-ext-funcs). mconf is started on a 160x64 characters terminal;
init_wsize at mconf.c detects 160x64 characters terminal by a TIOCGWINSZ ioctl and
saves result as (cols, rows). initscr at lib_initscr.c (libncurses) loads "linux"
terminfo sees it has (0, 0) default, then checks LINES and COLUMNS env vars,
doesn't find them and finally defaults to 80x24 characters keeping result as
(COLS, LINES) global vars.
Each of dialog_checklist at checklist.c, dialog_inputbox at inputbox.c,
dialog_menu at menubox.c, dialog_msgbox at msgbox.c, dialog_textbox at textbox.c,
dialog_yesno at yesno.c has the code:
x = (COLS - width) / 2; /* x = (80 - 155) / 2 = -37 */
y = (LINES - height) / 2; /* y = (24 - 60) / 2 = -18 */
dialog = newwin (height, width, y, x);
keypad (dialog, TRUE);
newwin at lib_newwin.c returns NULL if any of its argument is less than 0, mconf
accepts it without check and causes SEGV.
Please have a look at the patch that changes mconf.c to use COLS and LINES
variables only. It also removes SIGWINCH handler in favour of libncurses' one,
because it caused the same trouble.
Thank You, and keep up with Your great work.
-------------- next part --------------
103d102
< static int rows, cols;
121,157d119
< static void init_wsize(void)
< {
< struct winsize ws;
< char *env;
<
< if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
< rows = 24;
< cols = 80;
< } else {
< rows = ws.ws_row;
< cols = ws.ws_col;
< if (!rows) {
< env = getenv("LINES");
< if (env)
< rows = atoi(env);
< if (!rows)
< rows = 24;
< }
< if (!cols) {
< env = getenv("COLUMNS");
< if (env)
< cols = atoi(env);
< if (!cols)
< cols = 80;
< }
< }
<
< if (rows < 19 || cols < 80) {
< fprintf(stderr, "Your display is too small to run Menuconfig!\n");
< fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
< exit(1);
< }
<
< rows -= 4;
< cols -= 5;
< }
<
391c353
< menu_instructions, rows, cols, rows - 10,
---
> menu_instructions, LINES - 4, COLS - 5, LINES - 10,
486c448
< show_textbox(title, text, rows, cols);
---
> show_textbox(title, text, LINES - 4, COLS - 5);
635,658d596
< static void winch_handler(int sig)
< {
< struct winsize ws;
<
< if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
< rows = 24;
< cols = 80;
< } else {
< rows = ws.ws_row;
< cols = ws.ws_col;
< }
<
< if (rows < 19 || cols < 80) {
< end_dialog();
< fprintf(stderr, "Your display is too small to run Menuconfig!\n");
< fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
< exit(1);
< }
<
< rows -= 4;
< cols -= 5;
<
< }
<
681d618
< init_wsize();
683d619
< signal(SIGWINCH, winch_handler);
More information about the uClibc
mailing list