lynx-dev
[Top][All Lists]
Advanced

[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);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]