diff options
| author | Paul Eggert <eggert@cs.ucla.edu> | 2011-04-06 20:34:05 -0700 | 
|---|---|---|
| committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-04-06 20:34:05 -0700 | 
| commit | 5fdb398c4b75b0c834aff7132f90b0ce5317a25a (patch) | |
| tree | 29ebb8fc5700fefdd867fa497eac27fb7d0bcfe0 | |
| parent | b189fa667ed7ac7b17f9665cd8a0c26316b3c521 (diff) | |
| download | emacs-5fdb398c4b75b0c834aff7132f90b0ce5317a25a.tar.gz | |
error: Print 32- and 64-bit integers portably (Bug#8435).
Without this change, on typical 64-bit hosts error ("...%d...", N)
was used to print both 32- and 64-bit integers N, which relied on
undefined behavior.
* lisp.h, src/m/amdx86-64.h, src/m/ia64.h, src/m/ibms390x.h (pEd):
New macro.
* lisp.h (error, verror): Mark as printf-like functions.
* eval.c (verror): Use vsnprintf, not doprnt, to do the real work.
Report overflow in size calculations when allocating printf buffer.
Do not truncate output string at its first null byte.
* xdisp.c (vmessage): Use vsnprintf, not doprnt, to do the real work.
Truncate the output at a character boundary, since vsnprintf does not
do that.
* charset.c (check_iso_charset_parameter): Convert internal
character to string before calling 'error', since %c now has the
printf meaning.
* coding.c (Fdecode_sjis_char, Fdecode_big5_char): Avoid int
overflow when computing char to be passed to 'error'.  Do not
pass Lisp_Object to 'error'; pass the integer instead.
* nsfns.m (Fns_do_applescript): Use int, not long, since it's
formatted with plain %d.
| -rw-r--r-- | src/ChangeLog | 22 | ||||
| -rw-r--r-- | src/category.c | 4 | ||||
| -rw-r--r-- | src/charset.c | 18 | ||||
| -rw-r--r-- | src/coding.c | 53 | ||||
| -rw-r--r-- | src/doc.c | 4 | ||||
| -rw-r--r-- | src/eval.c | 21 | ||||
| -rw-r--r-- | src/fns.c | 2 | ||||
| -rw-r--r-- | src/intervals.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 7 | ||||
| -rw-r--r-- | src/m/amdx86-64.h | 1 | ||||
| -rw-r--r-- | src/m/ia64.h | 1 | ||||
| -rw-r--r-- | src/m/ibms390x.h | 2 | ||||
| -rw-r--r-- | src/nsfns.m | 15 | ||||
| -rw-r--r-- | src/sysdep.c | 3 | ||||
| -rw-r--r-- | src/window.c | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 16 | ||||
| -rw-r--r-- | src/xfns.c | 2 | 
17 files changed, 117 insertions, 60 deletions
| diff --git a/src/ChangeLog b/src/ChangeLog index 6f2509429d2..c1bea6b4cc7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,27 @@  2011-04-07  Paul Eggert  <eggert@cs.ucla.edu> +	error: Print 32- and 64-bit integers portably (Bug#8435). +	Without this change, on typical 64-bit hosts error ("...%d...", N) +	was used to print both 32- and 64-bit integers N, which relied on +	undefined behavior. +	* lisp.h, src/m/amdx86-64.h, src/m/ia64.h, src/m/ibms390x.h (pEd): +	New macro. +	* lisp.h (error, verror): Mark as printf-like functions. +	* eval.c (verror): Use vsnprintf, not doprnt, to do the real work. +	Report overflow in size calculations when allocating printf buffer. +	Do not truncate output string at its first null byte. +	* xdisp.c (vmessage): Use vsnprintf, not doprnt, to do the real work. +	Truncate the output at a character boundary, since vsnprintf does not +	do that. +	* charset.c (check_iso_charset_parameter): Convert internal +	character to string before calling 'error', since %c now has the +	printf meaning. +	* coding.c (Fdecode_sjis_char, Fdecode_big5_char): Avoid int +	overflow when computing char to be passed to 'error'.  Do not +	pass Lisp_Object to 'error'; pass the integer instead. +	* nsfns.m (Fns_do_applescript): Use int, not long, since it's +	formatted with plain %d. +  	* eval.c (internal_lisp_condition_case): Don't pass spurious arg.  	* keyboard.c (access_keymap_keyremap): Print func name, not garbage. diff --git a/src/category.c b/src/category.c index cc7ff88474f..bba030360c4 100644 --- a/src/category.c +++ b/src/category.c @@ -128,7 +128,7 @@ the current buffer's category table.  */)    table = check_category_table (table);    if (!NILP (CATEGORY_DOCSTRING (table, XFASTINT (category)))) -    error ("Category `%c' is already defined", XFASTINT (category)); +    error ("Category `%c' is already defined", (int) XFASTINT (category));    if (!NILP (Vpurify_flag))      docstring = Fpurecopy (docstring);    CATEGORY_DOCSTRING (table, XFASTINT (category)) = docstring; @@ -373,7 +373,7 @@ then delete CATEGORY from the category set instead of adding it.  */)    table = check_category_table (table);    if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category)))) -    error ("Undefined category: %c", XFASTINT (category)); +    error ("Undefined category: %c", (int) XFASTINT (category));    set_value = NILP (reset) ? Qt : Qnil; diff --git a/src/charset.c b/src/charset.c index 32836d459f3..55cbfc4a399 100644 --- a/src/charset.c +++ b/src/charset.c @@ -493,7 +493,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co    unbind_to (count, Qnil);    if (fd < 0        || ! (fp = fdopen (fd, "r"))) -    error ("Failure in loading charset map: %S", SDATA (mapfile)); +    error ("Failure in loading charset map: %s", SDATA (mapfile));    /* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is       large (larger than MAX_ALLOCA).  */ @@ -1000,7 +1000,7 @@ usage: (define-charset-internal ...)  */)      {        CHECK_NUMBER (val);        if (XINT (val) < '0' || XINT (val) > 127) -	error ("Invalid iso-final-char: %d", XINT (val)); +	error ("Invalid iso-final-char: %"pEd, XINT (val));        charset.iso_final = XINT (val);      } @@ -1022,7 +1022,7 @@ usage: (define-charset-internal ...)  */)      {        CHECK_NATNUM (val);        if ((XINT (val) > 0 && XINT (val) <= 128) || XINT (val) >= 256) -	error ("Invalid emacs-mule-id: %d", XINT (val)); +	error ("Invalid emacs-mule-id: %"pEd, XINT (val));        charset.emacs_mule_id = XINT (val);      } @@ -1440,11 +1440,17 @@ check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, Lisp_Obje    CHECK_NATNUM (final_char);    if (XINT (dimension) > 3) -    error ("Invalid DIMENSION %d, it should be 1, 2, or 3", XINT (dimension)); +    error ("Invalid DIMENSION %"pEd", it should be 1, 2, or 3", +	   XINT (dimension));    if (XINT (chars) != 94 && XINT (chars) != 96) -    error ("Invalid CHARS %d, it should be 94 or 96", XINT (chars)); +    error ("Invalid CHARS %"pEd", it should be 94 or 96", XINT (chars));    if (XINT (final_char) < '0' || XINT (final_char) > '~') -    error ("Invalid FINAL-CHAR %c, it should be `0'..`~'", XINT (chars)); +    { +      unsigned char str[MAX_MULTIBYTE_LENGTH + 1]; +      int len = CHAR_STRING (XINT (chars), str); +      str[len] = '\0'; +      error ("Invalid FINAL-CHAR %s, it should be `0'..`~'", str); +    }  } diff --git a/src/coding.c b/src/coding.c index 798e5c533f6..f099605c774 100644 --- a/src/coding.c +++ b/src/coding.c @@ -9023,14 +9023,15 @@ Return the corresponding character.  */)  {    Lisp_Object spec, attrs, val;    struct charset *charset_roman, *charset_kanji, *charset_kana, *charset; -  EMACS_INT c; +  EMACS_INT ch; +  int c;    CHECK_NATNUM (code); -  c = XFASTINT (code); +  ch = XFASTINT (code);    CHECK_CODING_SYSTEM_GET_SPEC (Vsjis_coding_system, spec);    attrs = AREF (spec, 0); -  if (ASCII_BYTE_P (c) +  if (ASCII_BYTE_P (ch)        && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))      return code; @@ -9039,27 +9040,31 @@ Return the corresponding character.  */)    charset_kana = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);    charset_kanji = CHARSET_FROM_ID (XINT (XCAR (val))); -  if (c <= 0x7F) -    charset = charset_roman; -  else if (c >= 0xA0 && c < 0xDF) +  if (ch <= 0x7F) +    { +      c = ch; +      charset = charset_roman; +    } +  else if (ch >= 0xA0 && ch < 0xDF)      { +      c = ch - 0x80;        charset = charset_kana; -      c -= 0x80;      }    else      { -      EMACS_INT c1 = c >> 8; -      int c2 = c & 0xFF; +      EMACS_INT c1 = ch >> 8; +      int c2 = ch & 0xFF;        if (c1 < 0x81 || (c1 > 0x9F && c1 < 0xE0) || c1 > 0xEF  	  || c2 < 0x40 || c2 == 0x7F || c2 > 0xFC) -	error ("Invalid code: %d", code); +	error ("Invalid code: %"pEd, ch); +      c = ch;        SJIS_TO_JIS (c);        charset = charset_kanji;      }    c = DECODE_CHAR (charset, c);    if (c < 0) -    error ("Invalid code: %d", code); +    error ("Invalid code: %"pEd, ch);    return make_number (c);  } @@ -9099,14 +9104,15 @@ Return the corresponding character.  */)  {    Lisp_Object spec, attrs, val;    struct charset *charset_roman, *charset_big5, *charset; +  EMACS_INT ch;    int c;    CHECK_NATNUM (code); -  c = XFASTINT (code); +  ch = XFASTINT (code);    CHECK_CODING_SYSTEM_GET_SPEC (Vbig5_coding_system, spec);    attrs = AREF (spec, 0); -  if (ASCII_BYTE_P (c) +  if (ASCII_BYTE_P (ch)        && ! NILP (CODING_ATTR_ASCII_COMPAT (attrs)))      return code; @@ -9114,19 +9120,24 @@ Return the corresponding character.  */)    charset_roman = CHARSET_FROM_ID (XINT (XCAR (val))), val = XCDR (val);    charset_big5 = CHARSET_FROM_ID (XINT (XCAR (val))); -  if (c <= 0x7F) -    charset = charset_roman; +  if (ch <= 0x7F) +    { +      c = ch; +      charset = charset_roman; +    }    else      { -      int b1 = c >> 8, b2 = c & 0x7F; +      EMACS_INT b1 = ch >> 8; +      int b2 = ch & 0x7F;        if (b1 < 0xA1 || b1 > 0xFE  	  || b2 < 0x40 || (b2 > 0x7E && b2 < 0xA1) || b2 > 0xFE) -	error ("Invalid code: %d", code); +	error ("Invalid code: %"pEd, ch); +      c = ch;        charset = charset_big5;      } -  c = DECODE_CHAR (charset, (unsigned )c); +  c = DECODE_CHAR (charset, c);    if (c < 0) -    error ("Invalid code: %d", code); +    error ("Invalid code: %"pEd, ch);    return make_number (c);  } @@ -9298,7 +9309,7 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS...)  */)  	|| (EQ (operation, Qinsert_file_contents) && CONSP (target)  	    && STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))  	|| (EQ (operation, Qopen_network_stream) && INTEGERP (target)))) -    error ("Invalid %dth argument", XFASTINT (target_idx) + 1); +    error ("Invalid %"pEd"th argument", XFASTINT (target_idx) + 1);    if (CONSP (target))      target = XCAR (target); @@ -9774,7 +9785,7 @@ usage: (define-coding-system-internal ...)  */)  	  CHECK_CHARSET_GET_ID (tmp1, id);  	  CHECK_NATNUM_CDR (val);  	  if (XINT (XCDR (val)) >= 4) -	    error ("Invalid graphic register number: %d", XINT (XCDR (val))); +	    error ("Invalid graphic register number: %"pEd, XINT (XCDR (val)));  	  XSETCAR (val, make_number (id));  	} diff --git a/src/doc.c b/src/doc.c index 158b09790f7..ed0d2323ed5 100644 --- a/src/doc.c +++ b/src/doc.c @@ -154,7 +154,7 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition)    if (0 > lseek (fd, position - offset, 0))      {        emacs_close (fd); -      error ("Position %ld out of range in doc string file \"%s\"", +      error ("Position %"pEd" out of range in doc string file \"%s\"",  	     position, name);      } @@ -669,7 +669,7 @@ the same file name is found in the `doc-directory'.  */)  		; /* Just a source file name boundary marker.  Ignore it.  */  	      else -		error ("DOC file invalid at position %d", pos); +		error ("DOC file invalid at position %"pEd, pos);  	    }  	}        pos += end - buf; diff --git a/src/eval.c b/src/eval.c index 8b029967e7a..77411a911ee 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1977,21 +1977,26 @@ void  verror (const char *m, va_list ap)  {    char buf[200]; -  EMACS_INT size = 200; -  int mlen; +  size_t size = sizeof buf; +  size_t size_max = (size_t) -1;    char *buffer = buf;    int allocated = 0; +  int used;    Lisp_Object string; -  mlen = strlen (m); -    while (1)      { -      EMACS_INT used; -      used = doprnt (buffer, size, m, m + mlen, ap); +      used = vsnprintf (buffer, size, m, ap); +      if (used < 0) +	used = 0;        if (used < size)  	break; -      size *= 2; +      if (size <= size_max / 2) +	size *= 2; +      else if (size < size_max) +	size = size_max; +      else +	memory_full ();        if (allocated)  	buffer = (char *) xrealloc (buffer, size);        else @@ -2001,7 +2006,7 @@ verror (const char *m, va_list ap)  	}      } -  string = build_string (buffer); +  string = make_string (buffer, used);    if (allocated)      xfree (buffer); diff --git a/src/fns.c b/src/fns.c index c45d9e31ef2..09ce8c1b597 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1076,7 +1076,7 @@ an error is signaled.  */)        EMACS_INT converted = str_to_unibyte (SDATA (string), str, chars, 0);        if (converted < chars) -	error ("Can't convert the %dth character to unibyte", converted); +	error ("Can't convert the %"pEd"th character to unibyte", converted);        string = make_unibyte_string ((char *) str, chars);        xfree (str);      } diff --git a/src/intervals.c b/src/intervals.c index 729e6810f74..952f826778c 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -777,7 +777,7 @@ update_interval (register INTERVAL i, EMACS_INT pos)  	      i = i->right;		/* Move to the right child */  	    }  	  else if (NULL_PARENT (i)) -	    error ("Point %d after end of properties", pos); +	    error ("Point %"pEd" after end of properties", pos);  	  else              i = INTERVAL_PARENT (i);  	  continue; diff --git a/src/lisp.h b/src/lisp.h index 41a64d2f47d..7999fb42d5f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -38,6 +38,7 @@ extern void check_cons_list (void);  #ifndef EMACS_INT  #define EMACS_INT long  #define BITS_PER_EMACS_INT BITS_PER_LONG +#define pEd "ld"  #endif  #ifndef EMACS_UINT  #define EMACS_UINT unsigned long @@ -46,6 +47,7 @@ extern void check_cons_list (void);  #ifndef EMACS_INT  #define EMACS_INT int  #define BITS_PER_EMACS_INT BITS_PER_INT +#define pEd "d"  #endif  #ifndef EMACS_UINT  #define EMACS_UINT unsigned int @@ -2872,8 +2874,9 @@ extern Lisp_Object internal_condition_case_n (Lisp_Object (*) (size_t, Lisp_Obje  extern void specbind (Lisp_Object, Lisp_Object);  extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object);  extern Lisp_Object unbind_to (int, Lisp_Object); -extern void error (const char *, ...) NO_RETURN; -extern void verror (const char *, va_list) NO_RETURN; +extern void error (const char *, ...) NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 2); +extern void verror (const char *, va_list) +  NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 0);  extern void do_autoload (Lisp_Object, Lisp_Object);  extern Lisp_Object un_autoload (Lisp_Object);  EXFUN (Ffetch_bytecode, 1); diff --git a/src/m/amdx86-64.h b/src/m/amdx86-64.h index 441f41b4444..dbca9b5b838 100644 --- a/src/m/amdx86-64.h +++ b/src/m/amdx86-64.h @@ -28,6 +28,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */  /* Define the type to use.  */  #define EMACS_INT               long +#define pEd			"ld"  #define EMACS_UINT              unsigned long  /* Define XPNTR to avoid or'ing with DATA_SEG_BITS */ diff --git a/src/m/ia64.h b/src/m/ia64.h index 101d56e648b..a1374d7c224 100644 --- a/src/m/ia64.h +++ b/src/m/ia64.h @@ -28,6 +28,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */  /* Define the type to use.  */  #define EMACS_INT		long +#define pEd			"ld"  #define EMACS_UINT		unsigned long  #ifdef REL_ALLOC diff --git a/src/m/ibms390x.h b/src/m/ibms390x.h index d4ef5c291ef..14228b61e56 100644 --- a/src/m/ibms390x.h +++ b/src/m/ibms390x.h @@ -24,6 +24,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */  /* Define the type to use.  */  #define EMACS_INT long +#define pEd "ld"  #define EMACS_UINT unsigned long  /* On the 64 bit architecture, we can use 60 bits for addresses */ @@ -31,4 +32,3 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */  /* Define XPNTR to avoid or'ing with DATA_SEG_BITS */  #define XPNTR(a) XUINT (a) - diff --git a/src/nsfns.m b/src/nsfns.m index 6a5adbd7bf3..d4445d1d627 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -483,7 +483,7 @@ ns_set_name_internal (FRAME_PTR f, Lisp_Object name)    if (!STRINGP (f->icon_name))      encoded_icon_name = encoded_name;    else -    encoded_icon_name = ENCODE_UTF_8 (f->icon_name);     +    encoded_icon_name = ENCODE_UTF_8 (f->icon_name);    str = [NSString stringWithUTF8String: SDATA (encoded_icon_name)]; @@ -637,7 +637,7 @@ ns_set_name_as_filename (struct frame *f)    if (FRAME_ICONIFIED_P (f))      [[view window] setMiniwindowTitle: str]; -  else  +  else      {        NSString *fstr; @@ -1021,8 +1021,8 @@ frame_parm_handler ns_frame_parm_handlers[] =    0,  /* x_set_fullscreen will ignore */    x_set_font_backend, /* generic OK */    x_set_alpha, -  0, /* x_set_sticky */   -  0, /* x_set_tool_bar_position */   +  0, /* x_set_sticky */ +  0, /* x_set_tool_bar_position */  }; @@ -2044,7 +2044,7 @@ In case the execution fails, an error is signaled. */)       (Lisp_Object script)  {    Lisp_Object result; -  long status; +  int status;    CHECK_STRING (script);    check_ns (); @@ -2330,7 +2330,7 @@ If omitted or nil, that stands for the selected frame's display.  */)  {    struct ns_display_info *dpyinfo;    check_ns (); -   +    dpyinfo = check_ns_display_info (display);    /* We force 24+ bit depths to 24-bit to prevent an overflow.  */    return make_number (1 << min (dpyinfo->n_planes, 24)); @@ -2373,7 +2373,7 @@ compute_tip_xy (struct frame *f,        pt.y = x_display_pixel_height (FRAME_NS_DISPLAY_INFO (f)) - XINT (top)          - height;      } -   +    /* Ensure in bounds.  (Note, screen origin = lower left.) */    if (INTEGERP (left))      *root_x = pt.x; @@ -2655,4 +2655,3 @@ be used as the image of the icon representing the frame.  */);    check_window_system_func = check_ns;  } - diff --git a/src/sysdep.c b/src/sysdep.c index a165a9ca52f..f4f767dac3f 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2361,7 +2361,8 @@ serial_configure (struct Lisp_Process *p,    CHECK_NUMBER (tem);    err = cfsetspeed (&attr, XINT (tem));    if (err != 0) -    error ("cfsetspeed(%d) failed: %s", XINT (tem), emacs_strerror (errno)); +    error ("cfsetspeed(%"pEd") failed: %s", XINT (tem), +	   emacs_strerror (errno));    childp2 = Fplist_put (childp2, QCspeed, tem);    /* Configure bytesize.  */ diff --git a/src/window.c b/src/window.c index 5ca46dd3316..ebfd1b0f778 100644 --- a/src/window.c +++ b/src/window.c @@ -3804,7 +3804,7 @@ See Info node `(elisp)Splitting Windows' for more details and examples.  */)  	error ("Window height %d too small (after splitting)", size_int);        if (size_int + window_safe_height > XFASTINT (o->total_lines))  	error ("Window height %d too small (after splitting)", -	       XFASTINT (o->total_lines) - size_int); +	       (int) (XFASTINT (o->total_lines) - size_int));        if (NILP (o->parent)  	  || NILP (XWINDOW (o->parent)->vchild))  	{ @@ -3821,7 +3821,7 @@ See Info node `(elisp)Splitting Windows' for more details and examples.  */)  	error ("Window width %d too small (after splitting)", size_int);        if (size_int + window_safe_width > XFASTINT (o->total_cols))  	error ("Window width %d too small (after splitting)", -	       XFASTINT (o->total_cols) - size_int); +	       (int) (XFASTINT (o->total_cols) - size_int));        if (NILP (o->parent)  	  || NILP (XWINDOW (o->parent)->hchild))  	{ diff --git a/src/xdisp.c b/src/xdisp.c index 16954d0f809..a296fb33a9f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -8407,10 +8407,18 @@ vmessage (const char *m, va_list ap)  	{  	  if (m)  	    { -	      EMACS_INT len; - -	      len = doprnt (FRAME_MESSAGE_BUF (f), -			    FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap); +	      char *buf = FRAME_MESSAGE_BUF (f); +	      size_t bufsize = FRAME_MESSAGE_BUF_SIZE (f); +	      int len = vsnprintf (buf, bufsize, m, ap); +	      if (len < 0) +		len = 0; + +	      /* Do any truncation at a character boundary.  */ +	      if (0 < bufsize && bufsize <= len) +		for (len = bufsize - 1; +		     len && ! CHAR_HEAD_P (buf[len - 1]); +		     len--) +		  continue;  	      message2 (FRAME_MESSAGE_BUF (f), len, 0);  	    } diff --git a/src/xfns.c b/src/xfns.c index 8e5639681df..04b8e44b561 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -215,7 +215,7 @@ check_x_display_info (Lisp_Object object)        struct terminal *t = get_terminal (object, 1);        if (t->type != output_x_window) -        error ("Terminal %d is not an X display", XINT (object)); +        error ("Terminal %"pEd" is not an X display", XINT (object));        dpyinfo = t->display_info.x;      } | 
