🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Arne Henrik Juul Thu, 10 Sep 1992 18:48
FIX: Bash bombs on Meta-B on Cray
#887
Author: Arne Henrik Juul
Date: Thu, 10 Sep 1992 18:48
246 lines
8567 bytes
After some debugging, I have found the cause for the bug that was
posted here recently, which caused bash to fail on certain commands.

The problem is in the readline code: It uses a common field in its
keymap entry structure to refer to both a new keymap (for ESC
commands, Control-X commands etc.) and a function (for normal keys).
But this is *not* done as a union, because it then becomes difficult
(maybe impossible) to initalize in the way wanted, as the comment in
the keymaps.h file says:

typedef struct _keymap_entry {
  char type;
  Function *function;
} KEYMAP_ENTRY;

/* I wanted to make the above structure contain a union of:
   union { Function *function; struct _keymap_entry *keymap; } value;
   but this made it impossible for me to create a static array.
   Maybe I need C lessons. */

The function field is also used as a Keymap variable (really a
(struct _keymap_entry *)) in various places, and it is initalized by
taking a KEYMAP_ENTRY_ARRAY and just casting it to (Function *).
When it is again used (in rl_dispatch) it is cast back to (Keymap).

On the Cray, this just does not work properly, and I'm not sure if it
is required to - casting between pointer to structure and pointer to
function and back is not very clean. The net effect is that the
pointer is divided by four, as far as I can see. This makes bash jump
off into never-never land, quite literally, by following a bogus
(Function *) pointer.

The easy workaround is just to add another field to the struct
_keymap_entry, like this:

typedef struct _keymap_entry {
  char type;
  Function *function;
  struct _keymap_entry *map;
} KEYMAP_ENTRY;


This wastes some space (but who cares about 60KB on the Cray :-), but
it works. The real problem is to find all occurences of
(something).function and find out if it needs to be replaced with
-----------.map.  I have done this some places, but I may have missed
some.

There may be a related problem with the macro stuff which *also* seems
to overload the same field, but I didn't worry about that for now - I
don't use macros in bash anyway :-)

At the end find enclosed my current diffs for this problem, use at own
risk, warranty void if used, totally untested etc.

Regards,

Arne H. Juul  --  arnej@lise.unit.no  --  University of Trondheim, Norway


diff -rc bash-1.12.dist/lib/readline/emacs_keymap.c bash-1.12.ok/lib/readline/emacs_keymap.c
*** bash-1.12.dist/lib/readline/emacs_keymap.c	Tue Jul  9 13:10:28 1991
--- bash-1.12.ok/lib/readline/emacs_keymap.c	Thu Sep 10 04:54:33 1992
***************
*** 56,65 ****
    { ISFUNC, rl_unix_line_discard },	/* Control-u */
    { ISFUNC, rl_quoted_insert },		/* Control-v */
    { ISFUNC, rl_unix_word_rubout },	/* Control-w */
!   { ISKMAP, (Function *)emacs_ctlx_keymap },	/* Control-x */
    { ISFUNC, rl_yank },			/* Control-y */
    { ISFUNC, (Function *)0x0 },		/* Control-z */
!   { ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
    { ISFUNC, (Function *)0x0 },		/* Control-\ */
    { ISFUNC, (Function *)0x0 },		/* Control-] */
    { ISFUNC, (Function *)0x0 },		/* Control-^ */
--- 56,65 ----
    { ISFUNC, rl_unix_line_discard },	/* Control-u */
    { ISFUNC, rl_quoted_insert },		/* Control-v */
    { ISFUNC, rl_unix_word_rubout },	/* Control-w */
!   { ISKMAP, 0, emacs_ctlx_keymap },	/* Control-x */
    { ISFUNC, rl_yank },			/* Control-y */
    { ISFUNC, (Function *)0x0 },		/* Control-z */
!   { ISKMAP, 0, emacs_meta_keymap },     /* Control-[ */
    { ISFUNC, (Function *)0x0 },		/* Control-\ */
    { ISFUNC, (Function *)0x0 },		/* Control-] */
    { ISFUNC, (Function *)0x0 },		/* Control-^ */
diff -rc bash-1.12.dist/lib/readline/keymaps.c bash-1.12.ok/lib/readline/keymaps.c
*** bash-1.12.dist/lib/readline/keymaps.c	Sun Aug  4 18:54:07 1991
--- bash-1.12.ok/lib/readline/keymaps.c	Thu Sep 10 04:55:20 1992
***************
*** 120,126 ****
  	  break;
  
  	case ISKMAP:
! 	  rl_discard_keymap ((Keymap)map[i].function);
  	  break;
  
  	case ISMACR:
--- 120,126 ----
  	  break;
  
  	case ISKMAP:
! 	  rl_discard_keymap (map[i].map);
  	  break;
  
  	case ISMACR:
diff -rc bash-1.12.dist/lib/readline/keymaps.h bash-1.12.ok/lib/readline/keymaps.h
*** bash-1.12.dist/lib/readline/keymaps.h	Tue Jul  9 13:10:30 1991
--- bash-1.12.ok/lib/readline/keymaps.h	Thu Sep 10 04:53:40 1992
***************
*** 18,23 ****
--- 18,24 ----
  typedef struct _keymap_entry {
    char type;
    Function *function;
+   struct _keymap_entry *map;
  } KEYMAP_ENTRY;
  
  /* I wanted to make the above structure contain a union of:
diff -rc bash-1.12.dist/lib/readline/vi_keymap.c bash-1.12.ok/lib/readline/vi_keymap.c
*** bash-1.12.dist/lib/readline/vi_keymap.c	Tue Jul  9 13:10:32 1991
--- bash-1.12.ok/lib/readline/vi_keymap.c	Thu Sep 10 04:57:56 1992
***************
*** 59,65 ****
    { ISFUNC, rl_yank },			/* Control-y */
    { ISFUNC, (Function *)0x0 },		/* Control-z */
  
!   { ISKMAP, (Function *)vi_escape_keymap }, /* Control-[ */
    { ISFUNC, (Function *)0x0 },		/* Control-\ */
    { ISFUNC, (Function *)0x0 },		/* Control-] */
    { ISFUNC, (Function *)0x0 },		/* Control-^ */
--- 59,65 ----
    { ISFUNC, rl_yank },			/* Control-y */
    { ISFUNC, (Function *)0x0 },		/* Control-z */
  
!   { ISKMAP, 0, vi_escape_keymap }, /* Control-[ */
    { ISFUNC, (Function *)0x0 },		/* Control-\ */
    { ISFUNC, (Function *)0x0 },		/* Control-] */
    { ISFUNC, (Function *)0x0 },		/* Control-^ */
*** bash-1.12.dist/lib/readline/readline.c	Sun Jan 26 19:31:11 1992
--- bash-1.12.ok/lib/readline/readline.c	Thu Sep 10 21:31:08 1992
***************
*** 844,850 ****
      {
        if (map[ESC].type == ISKMAP)
  	{
! 	  map = (Keymap)map[ESC].function;
  	  key -= 128;
  	  rl_dispatch (key, map);
  	}
--- 844,850 ----
      {
        if (map[ESC].type == ISKMAP)
  	{
! 	  map = map[ESC].map;
  	  key -= 128;
  	  rl_dispatch (key, map);
  	}
***************
*** 885,897 ****
        break;
  
      case ISKMAP:
!       if (map[key].function != (Function *)NULL)
  	{
  	  int newkey;
  
  	  rl_key_sequence_length++;
  	  newkey = rl_read_key ();
! 	  rl_dispatch (newkey, (Keymap)map[key].function);
  	}
        else
  	{
--- 885,897 ----
        break;
  
      case ISKMAP:
!       if (map[key].map != NULL)
  	{
  	  int newkey;
  
  	  rl_key_sequence_length++;
  	  newkey = rl_read_key ();
! 	  rl_dispatch (newkey, map[key].map);
  	}
        else
  	{
***************
*** 5312,5318 ****
      {
        if (keymap[ESC].type == ISKMAP)
  	{
! 	  Keymap escmap = (Keymap)keymap[ESC].function;
  
  	  key -= 128;
  	  escmap[key].type = ISFUNC;
--- 5312,5318 ----
      {
        if (keymap[ESC].type == ISKMAP)
  	{
! 	  Keymap escmap = keymap[ESC].map;
  
  	  key -= 128;
  	  escmap[key].type = ISFUNC;
***************
*** 5435,5443 ****
  		free ((char *)map[i].function);
  
  	      map[keys[i]].type = ISKMAP;
! 	      map[keys[i]].function = (Function *)rl_make_bare_keymap ();
  	    }
! 	  map = (Keymap)map[keys[i]].function;
  	}
        else
  	{
--- 5435,5443 ----
  		free ((char *)map[i].function);
  
  	      map[keys[i]].type = ISKMAP;
! 	      map[keys[i]].map = rl_make_bare_keymap ();
  	    }
! 	  map = map[keys[i]].map;
  	}
        else
  	{
***************
*** 6131,6139 ****
  
  	    /* Find the list of keyseqs in this map which have FUNCTION as
  	       their target.  Add the key sequences found to RESULT. */
! 	    if (map[key].function)
  	      seqs =
! 		invoking_keyseqs_in_map (function, (Keymap)map[key].function);
  
  	    if (seqs)
  	      {
--- 6131,6139 ----
  
  	    /* Find the list of keyseqs in this map which have FUNCTION as
  	       their target.  Add the key sequences found to RESULT. */
! 	    if (map[key].map)
  	      seqs =
! 		invoking_keyseqs_in_map (function, map[key].map);
  
  	    if (seqs)
  	      {
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads