[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Lynx-dev] Segfault on pages w/ titles containing certain characters
From: |
Bake Timmons |
Subject: |
[Lynx-dev] Segfault on pages w/ titles containing certain characters |
Date: |
Fri, 20 Nov 2009 17:20:06 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux) |
Hi,
Lynx 2.8.8dev.1 segfaults on pages with titles containing certain
characters that are displayed in more than one cell.
Attached is one such web page and a patch.
System details:
Lynx Version 2.8.8dev.1 (28 Aug 2009)
libwww-FM 2.14, SSL-MM 1.4.1,, ncurses 5.7.20090803(wide)
uname -a
Linux XXX 2.6.31.5-libre1 #1 SMP Mon Nov 9 06:34:53 EST 2009 x86_64 GNU/Linux
LANG=en_US.UTF-8
Some relevant options from lynx.cfg:
CHARACTER_SET:iso-8859-1
PREPEND_CHARSET_TO_SOURCE:FALSE
PREFERRED_LANGUAGE:en
SHOW_CURSOR:TRUE
Backtrace:
(gdb) bt
#0 0x00007ffff763cf25 in *__GI_raise (sig=<value optimized out>)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x00007ffff763fd60 in *__GI_abort () at abort.c:88
#2 0x00007ffff767255d in __libc_message (do_abort=2,
fmt=0x7fffffffcb30 "ffff7dfe000 r-xp 00000000 08:01 686699", ' ' <repeats
21 times>, "/lib/ld-2.10.1.so\n7ffff7e68000-7ffff7fe9000 r--p 00000000 08:01
646306", ' ' <repeats 21 times>,
"/usr/lib/locale/locale-archive\n7ffff7fe9000-7ffff7"...) at
../sysdeps/unix/sysv/linux/libc_fatal.c:173
#3 0x00007ffff767bdb6 in malloc_printerr (action=3,
str=0x7ffff7726418 "free(): invalid next size (fast)",
ptr=<value optimized out>) at malloc.c:6217
#4 0x00007ffff76806fc in *__GI___libc_free (mem=<value optimized out>)
at malloc.c:3716
#5 0x0000000000416d5c in display_title (text=0x941e20) at GridText.c:1813
#6 0x000000000041713f in display_page (text=0x941e20, line_number=0,
target=0x0) at GridText.c:2082
#7 0x0000000000421820 in HText_pageDisplay (line_num=1, target=0x798240 "")
at GridText.c:7031
#8 0x0000000000442439 in mainloop () at LYMainLoop.c:6265
#9 0x0000000000433929 in main (argc=2, argv=0x7fffffffdf48) at LYMain.c:2167
Consider this excerpt from display_title() :
#ifdef WIDEC_CURSES
i = limit - LYbarWidth - strlen(percent) - LYstrCells(title);
if (i <= 0) { /* title is truncated */
i = limit - LYbarWidth - strlen(percent) - 3;
if (i <= 0) { /* no room at all */
title[0] = '\0';
} else {
strcpy(title + LYstrExtent2(title, i), "...");
}
i = 0;
}
LYmove(0, i);
#else
What happens is that the variable i, which counts cells, is used to
determine where to modify the title string by truncating and adding
"...". However, LYstrExtent2() returns a count of cells, not a count of
characters, which is necessary for strcpy(). Thus, because some
characters may be displayed in more than one cell, it may happen that
"..." is copied to a location beyond the end of the string, leading to a
segfault.
An appropriate function (and call) which returns the correct number of
characters is included in the attached patch.
Thanks for this wonderful program!
Best regards,
Bake
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
%%% Created Fri Nov 20 15:29:25 EST 2009 by target lynx.patch. %%%
diff -bru orig/lynx2-8-8/src/GridText.c lynx2-8-8/src/GridText.c
--- orig/lynx2-8-8/src/GridText.c 2009-06-06 20:30:35.000000000 -0400
+++ lynx2-8-8/src/GridText.c 2009-11-20 15:28:45.000000000 -0500
@@ -1779,7 +1779,7 @@
if (i <= 0) { /* no room at all */
title[0] = '\0';
} else {
- strcpy(title + LYstrExtent2(title, i), "...");
+ strcpy(title + LYstrFittable(title, i), "...");
}
i = 0;
}
diff -bru orig/lynx2-8-8/src/LYCurses.c lynx2-8-8/src/LYCurses.c
--- orig/lynx2-8-8/src/LYCurses.c 2009-04-26 12:24:31.000000000 -0400
+++ lynx2-8-8/src/LYCurses.c 2009-11-20 14:34:10.000000000 -0500
@@ -1973,28 +1973,19 @@
/*
* Determine the number of cells the given string would take up on the screen,
- * limited by the maxCells parameter. This is used for constructing aligned
- * text in the options and similar forms.
- *
- * FIXME: make this account for wrapping, too.
- * FIXME: make this useful for "lynx -dump", which hasn't initialized curses.
+ * limited (in the case of wide characters) by the maxCells parameter.
+ * If the returnCellNum parameter is TRUE, return the number of cells;
otherwise,
+ * return the length (limited by the len parameter) of the prefix of the string
+ * that fits in maxCells cells.
*/
-int LYstrExtent(const char *string, int len, int maxCells)
-{
- int result = 0;
- int used;
- if (len < 0)
- used = (int) strlen(string);
- else
- used = len;
-
- result = used;
+int LYstrExtent0(const char *s, int len, int maxCells, BOOL retCellNum)
+{
+ int used = (len < 0 ? (int) strlen(s) : len);
#ifdef WIDEC_CURSES
if (used > 0 && lynx_called_initscr) {
static WINDOW *fake_win;
static int fake_max;
- int n;
if (fake_max < maxCells) {
fake_max = (maxCells + 1) * 2;
@@ -2009,24 +2000,38 @@
if (fake_win != 0) {
int new_x = 0;
int new_y = 0;
+ int x = 0;
+ int n;
- result = 0;
wmove(fake_win, 0, 0);
for (n = 0; n < used; ++n) {
- if (IsNormalChar(string[n])) {
- waddch(fake_win, UCH(string[n]));
+ if (IsNormalChar(s[n])) {
+ waddch(fake_win, UCH(s[n]));
getyx(fake_win, new_y, new_x);
if (new_y > 0 || new_x > maxCells)
break;
- result = new_x;
+ x = new_x;
}
}
+ return (retCellNum ? x : n);
}
}
#endif
- if (result > maxCells)
- result = maxCells;
- return result;
+ return used;
+}
+
+/*
+ * Determine the number of cells the given string would take up on the screen,
+ * limited by the maxCells parameter. This is used for constructing aligned
+ * text in the options and similar forms.
+ *
+ * FIXME: make this account for wrapping, too.
+ * FIXME: make this useful for "lynx -dump", which hasn't initialized curses.
+ */
+int LYstrExtent(const char *string, int len, int maxCells)
+{
+ int result = LYstrExtent0(string, len, maxCells, TRUE);
+ return (result > maxCells ? maxCells : result);
}
/*
@@ -2042,6 +2047,15 @@
}
/*
+ * Determine the longest prefix of a string that fits in a given number of
cells
+ * and return its length.
+ */
+int LYstrFittable(const char *string, int maxCells)
+{
+ return LYstrExtent0(string, -1, maxCells, FALSE);
+}
+
+/*
* Returns the total number of cells that the string would use.
*/
int LYstrCells(const char *string)
diff -bru orig/lynx2-8-8/src/LYCurses.h lynx2-8-8/src/LYCurses.h
--- orig/lynx2-8-8/src/LYCurses.h 2009-04-26 12:24:31.000000000 -0400
+++ lynx2-8-8/src/LYCurses.h 2009-11-20 14:34:10.000000000 -0500
@@ -455,8 +455,10 @@
extern BOOLEAN setup(char *terminal);
extern int LYscreenHeight(void);
extern int LYscreenWidth(void);
+ extern int LYstrExtent0(const char *s, int len, int maxCells, BOOL
retCellNum);
extern int LYstrExtent(const char *string, int len, int maxCells);
extern int LYstrExtent2(const char *string, int len);
+ extern int LYstrFittable(const char *string, int maxCells);
extern int LYstrCells(const char *string);
extern void LYclear(void);
extern void LYclrtoeol(void);
- [Lynx-dev] Segfault on pages w/ titles containing certain characters,
Bake Timmons <=