home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / gnu / bash / bug / 601 < prev    next >
Encoding:
Text File  |  1992-09-10  |  8.1 KB  |  263 lines

  1. Newsgroups: gnu.bash.bug
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!kari.fm.unit.no!arnej
  3. From: arnej@kari.fm.unit.no (Arne Henrik Juul)
  4. Subject: FIX: Bash bombs on Meta-B on Cray
  5. Message-ID: <1992Sep10.204806@kari.fm.unit.no>
  6. Followup-To: gnu.bash.bug
  7. Keywords: bash,cray,bug
  8. Sender: gnulists@ai.mit.edu
  9. Reply-To: arnej@lise.unit.no
  10. Organization: Norwegian Institute of Technology
  11. Distribution: gnu
  12. Date: Thu, 10 Sep 1992 18:48:06 GMT
  13. Approved: bug-bash@prep.ai.mit.edu
  14. Lines: 247
  15.  
  16. After some debugging, I have found the cause for the bug that was
  17. posted here recently, which caused bash to fail on certain commands.
  18.  
  19. The problem is in the readline code: It uses a common field in its
  20. keymap entry structure to refer to both a new keymap (for ESC
  21. commands, Control-X commands etc.) and a function (for normal keys).
  22. But this is *not* done as a union, because it then becomes difficult
  23. (maybe impossible) to initalize in the way wanted, as the comment in
  24. the keymaps.h file says:
  25.  
  26. typedef struct _keymap_entry {
  27.   char type;
  28.   Function *function;
  29. } KEYMAP_ENTRY;
  30.  
  31. /* I wanted to make the above structure contain a union of:
  32.    union { Function *function; struct _keymap_entry *keymap; } value;
  33.    but this made it impossible for me to create a static array.
  34.    Maybe I need C lessons. */
  35.  
  36. The function field is also used as a Keymap variable (really a
  37. (struct _keymap_entry *)) in various places, and it is initalized by
  38. taking a KEYMAP_ENTRY_ARRAY and just casting it to (Function *).
  39. When it is again used (in rl_dispatch) it is cast back to (Keymap).
  40.  
  41. On the Cray, this just does not work properly, and I'm not sure if it
  42. is required to - casting between pointer to structure and pointer to
  43. function and back is not very clean. The net effect is that the
  44. pointer is divided by four, as far as I can see. This makes bash jump
  45. off into never-never land, quite literally, by following a bogus
  46. (Function *) pointer.
  47.  
  48. The easy workaround is just to add another field to the struct
  49. _keymap_entry, like this:
  50.  
  51. typedef struct _keymap_entry {
  52.   char type;
  53.   Function *function;
  54.   struct _keymap_entry *map;
  55. } KEYMAP_ENTRY;
  56.  
  57.  
  58. This wastes some space (but who cares about 60KB on the Cray :-), but
  59. it works. The real problem is to find all occurences of
  60. (something).function and find out if it needs to be replaced with
  61. -----------.map.  I have done this some places, but I may have missed
  62. some.
  63.  
  64. There may be a related problem with the macro stuff which *also* seems
  65. to overload the same field, but I didn't worry about that for now - I
  66. don't use macros in bash anyway :-)
  67.  
  68. At the end find enclosed my current diffs for this problem, use at own
  69. risk, warranty void if used, totally untested etc.
  70.  
  71. Regards,
  72.  
  73. Arne H. Juul  --  arnej@lise.unit.no  --  University of Trondheim, Norway
  74.  
  75.  
  76. diff -rc bash-1.12.dist/lib/readline/emacs_keymap.c bash-1.12.ok/lib/readline/emacs_keymap.c
  77. *** bash-1.12.dist/lib/readline/emacs_keymap.c    Tue Jul  9 13:10:28 1991
  78. --- bash-1.12.ok/lib/readline/emacs_keymap.c    Thu Sep 10 04:54:33 1992
  79. ***************
  80. *** 56,65 ****
  81.     { ISFUNC, rl_unix_line_discard },    /* Control-u */
  82.     { ISFUNC, rl_quoted_insert },        /* Control-v */
  83.     { ISFUNC, rl_unix_word_rubout },    /* Control-w */
  84. !   { ISKMAP, (Function *)emacs_ctlx_keymap },    /* Control-x */
  85.     { ISFUNC, rl_yank },            /* Control-y */
  86.     { ISFUNC, (Function *)0x0 },        /* Control-z */
  87. !   { ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
  88.     { ISFUNC, (Function *)0x0 },        /* Control-\ */
  89.     { ISFUNC, (Function *)0x0 },        /* Control-] */
  90.     { ISFUNC, (Function *)0x0 },        /* Control-^ */
  91. --- 56,65 ----
  92.     { ISFUNC, rl_unix_line_discard },    /* Control-u */
  93.     { ISFUNC, rl_quoted_insert },        /* Control-v */
  94.     { ISFUNC, rl_unix_word_rubout },    /* Control-w */
  95. !   { ISKMAP, 0, emacs_ctlx_keymap },    /* Control-x */
  96.     { ISFUNC, rl_yank },            /* Control-y */
  97.     { ISFUNC, (Function *)0x0 },        /* Control-z */
  98. !   { ISKMAP, 0, emacs_meta_keymap },     /* Control-[ */
  99.     { ISFUNC, (Function *)0x0 },        /* Control-\ */
  100.     { ISFUNC, (Function *)0x0 },        /* Control-] */
  101.     { ISFUNC, (Function *)0x0 },        /* Control-^ */
  102. diff -rc bash-1.12.dist/lib/readline/keymaps.c bash-1.12.ok/lib/readline/keymaps.c
  103. *** bash-1.12.dist/lib/readline/keymaps.c    Sun Aug  4 18:54:07 1991
  104. --- bash-1.12.ok/lib/readline/keymaps.c    Thu Sep 10 04:55:20 1992
  105. ***************
  106. *** 120,126 ****
  107.         break;
  108.   
  109.       case ISKMAP:
  110. !       rl_discard_keymap ((Keymap)map[i].function);
  111.         break;
  112.   
  113.       case ISMACR:
  114. --- 120,126 ----
  115.         break;
  116.   
  117.       case ISKMAP:
  118. !       rl_discard_keymap (map[i].map);
  119.         break;
  120.   
  121.       case ISMACR:
  122. diff -rc bash-1.12.dist/lib/readline/keymaps.h bash-1.12.ok/lib/readline/keymaps.h
  123. *** bash-1.12.dist/lib/readline/keymaps.h    Tue Jul  9 13:10:30 1991
  124. --- bash-1.12.ok/lib/readline/keymaps.h    Thu Sep 10 04:53:40 1992
  125. ***************
  126. *** 18,23 ****
  127. --- 18,24 ----
  128.   typedef struct _keymap_entry {
  129.     char type;
  130.     Function *function;
  131. +   struct _keymap_entry *map;
  132.   } KEYMAP_ENTRY;
  133.   
  134.   /* I wanted to make the above structure contain a union of:
  135. diff -rc bash-1.12.dist/lib/readline/vi_keymap.c bash-1.12.ok/lib/readline/vi_keymap.c
  136. *** bash-1.12.dist/lib/readline/vi_keymap.c    Tue Jul  9 13:10:32 1991
  137. --- bash-1.12.ok/lib/readline/vi_keymap.c    Thu Sep 10 04:57:56 1992
  138. ***************
  139. *** 59,65 ****
  140.     { ISFUNC, rl_yank },            /* Control-y */
  141.     { ISFUNC, (Function *)0x0 },        /* Control-z */
  142.   
  143. !   { ISKMAP, (Function *)vi_escape_keymap }, /* Control-[ */
  144.     { ISFUNC, (Function *)0x0 },        /* Control-\ */
  145.     { ISFUNC, (Function *)0x0 },        /* Control-] */
  146.     { ISFUNC, (Function *)0x0 },        /* Control-^ */
  147. --- 59,65 ----
  148.     { ISFUNC, rl_yank },            /* Control-y */
  149.     { ISFUNC, (Function *)0x0 },        /* Control-z */
  150.   
  151. !   { ISKMAP, 0, vi_escape_keymap }, /* Control-[ */
  152.     { ISFUNC, (Function *)0x0 },        /* Control-\ */
  153.     { ISFUNC, (Function *)0x0 },        /* Control-] */
  154.     { ISFUNC, (Function *)0x0 },        /* Control-^ */
  155. *** bash-1.12.dist/lib/readline/readline.c    Sun Jan 26 19:31:11 1992
  156. --- bash-1.12.ok/lib/readline/readline.c    Thu Sep 10 21:31:08 1992
  157. ***************
  158. *** 844,850 ****
  159.       {
  160.         if (map[ESC].type == ISKMAP)
  161.       {
  162. !       map = (Keymap)map[ESC].function;
  163.         key -= 128;
  164.         rl_dispatch (key, map);
  165.       }
  166. --- 844,850 ----
  167.       {
  168.         if (map[ESC].type == ISKMAP)
  169.       {
  170. !       map = map[ESC].map;
  171.         key -= 128;
  172.         rl_dispatch (key, map);
  173.       }
  174. ***************
  175. *** 885,897 ****
  176.         break;
  177.   
  178.       case ISKMAP:
  179. !       if (map[key].function != (Function *)NULL)
  180.       {
  181.         int newkey;
  182.   
  183.         rl_key_sequence_length++;
  184.         newkey = rl_read_key ();
  185. !       rl_dispatch (newkey, (Keymap)map[key].function);
  186.       }
  187.         else
  188.       {
  189. --- 885,897 ----
  190.         break;
  191.   
  192.       case ISKMAP:
  193. !       if (map[key].map != NULL)
  194.       {
  195.         int newkey;
  196.   
  197.         rl_key_sequence_length++;
  198.         newkey = rl_read_key ();
  199. !       rl_dispatch (newkey, map[key].map);
  200.       }
  201.         else
  202.       {
  203. ***************
  204. *** 5312,5318 ****
  205.       {
  206.         if (keymap[ESC].type == ISKMAP)
  207.       {
  208. !       Keymap escmap = (Keymap)keymap[ESC].function;
  209.   
  210.         key -= 128;
  211.         escmap[key].type = ISFUNC;
  212. --- 5312,5318 ----
  213.       {
  214.         if (keymap[ESC].type == ISKMAP)
  215.       {
  216. !       Keymap escmap = keymap[ESC].map;
  217.   
  218.         key -= 128;
  219.         escmap[key].type = ISFUNC;
  220. ***************
  221. *** 5435,5443 ****
  222.           free ((char *)map[i].function);
  223.   
  224.             map[keys[i]].type = ISKMAP;
  225. !           map[keys[i]].function = (Function *)rl_make_bare_keymap ();
  226.           }
  227. !       map = (Keymap)map[keys[i]].function;
  228.       }
  229.         else
  230.       {
  231. --- 5435,5443 ----
  232.           free ((char *)map[i].function);
  233.   
  234.             map[keys[i]].type = ISKMAP;
  235. !           map[keys[i]].map = rl_make_bare_keymap ();
  236.           }
  237. !       map = map[keys[i]].map;
  238.       }
  239.         else
  240.       {
  241. ***************
  242. *** 6131,6139 ****
  243.   
  244.           /* Find the list of keyseqs in this map which have FUNCTION as
  245.              their target.  Add the key sequences found to RESULT. */
  246. !         if (map[key].function)
  247.             seqs =
  248. !         invoking_keyseqs_in_map (function, (Keymap)map[key].function);
  249.   
  250.           if (seqs)
  251.             {
  252. --- 6131,6139 ----
  253.   
  254.           /* Find the list of keyseqs in this map which have FUNCTION as
  255.              their target.  Add the key sequences found to RESULT. */
  256. !         if (map[key].map)
  257.             seqs =
  258. !         invoking_keyseqs_in_map (function, map[key].map);
  259.   
  260.           if (seqs)
  261.             {
  262.  
  263.