home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.bash.bug
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!kari.fm.unit.no!arnej
- From: arnej@kari.fm.unit.no (Arne Henrik Juul)
- Subject: FIX: Bash bombs on Meta-B on Cray
- Message-ID: <1992Sep10.204806@kari.fm.unit.no>
- Followup-To: gnu.bash.bug
- Keywords: bash,cray,bug
- Sender: gnulists@ai.mit.edu
- Reply-To: arnej@lise.unit.no
- Organization: Norwegian Institute of Technology
- Distribution: gnu
- Date: Thu, 10 Sep 1992 18:48:06 GMT
- Approved: bug-bash@prep.ai.mit.edu
- Lines: 247
-
- 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)
- {
-
-