From: "Richard M. Stallman" <rms@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: potential bug in display_mode_element?
Date: Mon, 12 Sep 2005 11:34:12 -0400 [thread overview]
Message-ID: <E1EEqJw-000858-HP@fencepost.gnu.org> (raw)
In-Reply-To: <E1EEceq-0000U4-00@etlken> (message from Kenichi Handa on Mon, 12 Sep 2005 09:58:52 +0900)
I think you are right about the bug, but I think your patch does not
completely fix it. This patch, which seems to work, should fix the bug
completely by accessing the string only through its Lisp object pointer.
*** xdisp.c 08 Sep 2005 20:35:28 -0400 1.1050
--- xdisp.c 12 Sep 2005 06:18:48 -0400
***************
*** 15949,15955 ****
{
/* A string: output it and check for %-constructs within it. */
unsigned char c;
! const unsigned char *this, *lisp_string;
if (!NILP (props) || risky)
{
--- 15949,15955 ----
{
/* A string: output it and check for %-constructs within it. */
unsigned char c;
! int offset = 0;
if (!NILP (props) || risky)
{
***************
*** 16007,16014 ****
}
}
! this = SDATA (elt);
! lisp_string = this;
if (literal)
{
--- 16007,16013 ----
}
}
! offset = 0;
if (literal)
{
***************
*** 16031,16072 ****
break;
}
while ((precision <= 0 || n < precision)
! && *this
&& (mode_line_target != MODE_LINE_DISPLAY
|| it->current_x < it->last_visible_x))
{
! const unsigned char *last = this;
/* Advance to end of string or next format specifier. */
! while ((c = *this++) != '\0' && c != '%')
;
! if (this - 1 != last)
{
int nchars, nbytes;
/* Output to end of string or up to '%'. Field width
is length of string. Don't output more than
PRECISION allows us. */
! --this;
! prec = c_string_width (last, this - last, precision - n,
&nchars, &nbytes);
switch (mode_line_target)
{
case MODE_LINE_NOPROP:
case MODE_LINE_TITLE:
! n += store_mode_line_noprop (last, 0, prec);
break;
case MODE_LINE_STRING:
{
! int bytepos = last - lisp_string;
int charpos = string_byte_to_char (elt, bytepos);
int endpos = (precision <= 0
! ? string_byte_to_char (elt,
! this - lisp_string)
: charpos + nchars);
n += store_mode_line_string (NULL,
--- 16030,16073 ----
break;
}
+ /* Handle the non-literal case. */
+
while ((precision <= 0 || n < precision)
! && SREF (elt, offset) != 0
&& (mode_line_target != MODE_LINE_DISPLAY
|| it->current_x < it->last_visible_x))
{
! int last_offset = offset;
/* Advance to end of string or next format specifier. */
! while ((c = SREF (elt, offset++)) != '\0' && c != '%')
;
! if (offset - 1 != last_offset)
{
int nchars, nbytes;
/* Output to end of string or up to '%'. Field width
is length of string. Don't output more than
PRECISION allows us. */
! offset--;
! prec = c_string_width (SDATA (elt) + last_offset,
! offset - last_offset, precision - n,
&nchars, &nbytes);
switch (mode_line_target)
{
case MODE_LINE_NOPROP:
case MODE_LINE_TITLE:
! n += store_mode_line_noprop (SDATA (elt) + last_offset, 0, prec);
break;
case MODE_LINE_STRING:
{
! int bytepos = last_offset;
int charpos = string_byte_to_char (elt, bytepos);
int endpos = (precision <= 0
! ? string_byte_to_char (elt, offset)
: charpos + nchars);
n += store_mode_line_string (NULL,
***************
*** 16077,16083 ****
break;
case MODE_LINE_DISPLAY:
{
! int bytepos = last - lisp_string;
int charpos = string_byte_to_char (elt, bytepos);
n += display_string (NULL, elt, Qnil, 0, charpos,
it, 0, prec, 0,
--- 16078,16084 ----
break;
case MODE_LINE_DISPLAY:
{
! int bytepos = last_offset;
int charpos = string_byte_to_char (elt, bytepos);
n += display_string (NULL, elt, Qnil, 0, charpos,
it, 0, prec, 0,
***************
*** 16088,16099 ****
}
else /* c == '%' */
{
! const unsigned char *percent_position = this;
/* Get the specified minimum width. Zero means
don't pad. */
field = 0;
! while ((c = *this++) >= '0' && c <= '9')
field = field * 10 + c - '0';
/* Don't pad beyond the total padding allowed. */
--- 16089,16100 ----
}
else /* c == '%' */
{
! int percent_position = offset;
/* Get the specified minimum width. Zero means
don't pad. */
field = 0;
! while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
field = field * 10 + c - '0';
/* Don't pad beyond the total padding allowed. */
***************
*** 16113,16119 ****
int bytepos, charpos;
unsigned char *spec;
! bytepos = percent_position - lisp_string;
charpos = (STRING_MULTIBYTE (elt)
? string_byte_to_char (elt, bytepos)
: bytepos);
--- 16114,16120 ----
int bytepos, charpos;
unsigned char *spec;
! bytepos = percent_position;
charpos = (STRING_MULTIBYTE (elt)
? string_byte_to_char (elt, bytepos)
: bytepos);
prev parent reply other threads:[~2005-09-12 15:34 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-12 0:58 potential bug in display_mode_element? Kenichi Handa
2005-09-12 8:04 ` Kim F. Storm
2005-09-12 11:54 ` Kenichi Handa
2005-09-12 12:41 ` Potential GC-related problems in compose_chars_in_text Kim F. Storm
2005-09-13 1:08 ` Kenichi Handa
2005-09-13 15:54 ` Richard M. Stallman
2005-09-14 7:29 ` Kenichi Handa
2005-09-15 2:41 ` Richard M. Stallman
2005-09-15 4:21 ` Kenichi Handa
2005-09-16 1:01 ` Richard M. Stallman
2005-09-16 15:39 ` Stefan Monnier
2005-09-17 13:39 ` Richard M. Stallman
2005-09-19 13:43 ` Stefan Monnier
2005-09-12 15:34 ` Richard M. Stallman [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1EEqJw-000858-HP@fencepost.gnu.org \
--to=rms@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.