emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

potential bug in display_mode_element?


From: Kenichi Handa
Subject: potential bug in display_mode_element?
Date: Mon, 12 Sep 2005 09:58:52 +0900

I got a bug report for emacs-unicode-2, and it seems that
the same bug exists in HEAD too.  The backtrace is this:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208118624 (LWP 29169)]
0x080b7349 in display_mode_element (it=0xbfffd1b0, depth=10, field_width=0, 
precision=-63, elt=164196259, props=138499373, risky=0) at xdisp.c:16136
16136           while ((precision <= 0 || n < precision)
(gdb) xbacktrace
"execute-extended-command"
"call-interactively"
(gdb) bt full
#0  0x080b7349 in display_mode_element (it=0xbfffd1b0, depth=10, field_width=0, 
precision=-63, elt=164196259, props=138499373, risky=0) at xdisp.c:16136
        c = 0 '\0'
        this = (const unsigned char *) 0xaf7a101 <Address 0xaf7a101 out of 
bounds>
        lisp_string = (const unsigned char *) 0xaf7a0fc <Address 0xaf7a0fc out 
of bounds>
        n = 5
        field = 138382657
        prec = 5
        literal = 0

Here the strange thing is that list_string points an address
out of bounds.  It is initialized as this:

        this = SDATA (elt);
        lisp_string = this;

        if (literal)
          /* omitted because not relevant now */

        while ((precision <= 0 || n < precision)
               && *this
               && (mode_line_target != MODE_LINE_DISPLAY
                   || it->current_x < it->last_visible_x))
          ...

and never changed in the while loop.  So the only reason I
can think of why the address pointed by list_string becomes
out of bound is that the string data of ELT was relocated in
the loop and the original address was returned to OS.
Actually, display_string is called in the loop, and it will
run Lisp code.

So, I think we meed this change.  What do you think?

*** xdisp.c     10 Sep 2005 09:35:12 +0900      1.1050
--- xdisp.c     10 Sep 2005 18:58:05 +0900      
***************
*** 16036,16042 ****
--- 16036,16047 ----
               && (mode_line_target != MODE_LINE_DISPLAY
                   || it->current_x < it->last_visible_x))
          {
+           /* Never change the value of LAST in this block.  */
            const unsigned char *last = this;
+           /* String data of ELT may be relocated.  In such a case,
+              OFFSET can be used to make THIS correctly points into
+              the string data of ELT.  */
+           int offset = this - SDATA (elt);
  
            /* Advance to end of string or next format specifier.  */
            while ((c = *this++) != '\0' && c != '%')
***************
*** 16171,16176 ****
--- 16176,16182 ----
                else /* c == 0 */
                  break;
              }
+           this = SDATA (elt) + offset + (this - last);
          }
        }
        break;

---
Kenichi Handa
address@hidden




reply via email to

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