gww@beatnix.UUCP (Gary Winiger) (03/13/88)
Subject: Vi core dumps on SIGINT input. +Fix Index: ucb/ex/{ex_vget.c, ex_vmain.c, ex_voper.c} 4.3BSD +Fix Description: As previously reported: When vi receives the a SIGINT, it can queue it as the input character ATTN (value -2). This character is returned by getkey() (peekkey()). In some cases, vi asks if the character received is an xxx with ``isxxx''. The ``isxxx'' macros index the array _ctype_[] to determine the type of the character. If _ctype_ begins on a page boundary and the previous page is not a valid page, a segment fault will occur. Thanks to Keith Bostic (bostic@ucbvax) for pointing out that my previous fix was narrow in scope and could better be done as follows. Repeat-By: vi foo <user types INTERRUPT character> When _ctype_ begins on a page boundary and the previous page is not valid. Fix: Guard against checking indexing _ctype_ when the character may be ATTN. The attached code solves this problem at Elxsi. Gary.. {ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww --------- cut --------- snip --------- :.,$w diff ------------- Index: ucb/ex/ex_vget.c *** /tmp/,RCSt1014232 Sat Mar 12 10:57:36 1988 --- ex_vget.c Sat Mar 12 10:56:47 1988 *************** *** 1,5 **** --- 1,13 ---- /* * $Log: ex_vget.c,v $ + * Revision 1.3 88/03/12 10:55:34 gww + * Correct guard against non-ascii index of _ctype_[]. Thanks to + * Keith Bostic (bostic@ucbvax). + * + * Revision 1.2 87/05/08 17:06:28 gww + * Check for ATTN (-2) before using isxxxx macro so as not to negatively + * index _ctype_[] and possibly get a segment fault. + * * Revision 1.1 86/12/23 18:16:10 gww * Initial revision * *************** *** 11,17 **** */ #ifndef lint ! static char *ERcsId = "$Header: ex_vget.c,v 1.1 86/12/23 18:16:10 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)ex_vget.c 6.8 (Berkeley) 6/7/85"; #endif not lint --- 19,25 ---- */ #ifndef lint ! static char *ERcsId = "$Header: ex_vget.c,v 1.3 88/03/12 10:55:34 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)ex_vget.c 6.8 (Berkeley) 6/7/85"; #endif not lint *************** *** 624,630 **** cnt = 0; for (;;) { c = getkey(); ! if (!isdigit(c)) break; cnt *= 10, cnt += c - '0'; } --- 632,638 ---- cnt = 0; for (;;) { c = getkey(); ! if (!isascii(c) || !isdigit(c)) break; cnt *= 10, cnt += c - '0'; } Index: ucb/ex/ex_vmain.c *** /tmp/,RCSt1014237 Sat Mar 12 10:57:51 1988 --- ex_vmain.c Sat Mar 12 10:56:54 1988 *************** *** 1,5 **** --- 1,13 ---- /* * $Log: ex_vmain.c,v $ + * Revision 1.3 88/03/12 10:56:48 gww + * Correct guard against non-ascii index of _ctype_[]. Thanks to + * Keith Bostic (bostic@ucbvax). + * + * Revision 1.2 87/05/08 17:08:01 gww + * Check for ATTN (-2) before using isxxxx macro so as not to negatively + * index _ctype_[] and possibly get a segment fault. + * * Revision 1.1 86/12/23 18:16:13 gww * Initial revision * *************** *** 11,17 **** */ #ifndef lint ! static char *ERcsId = "$Header: ex_vmain.c,v 1.1 86/12/23 18:16:13 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)ex_vmain.c 7.7 (Berkeley) 6/7/85"; #endif not lint --- 19,25 ---- */ #ifndef lint ! static char *ERcsId = "$Header: ex_vmain.c,v 1.3 88/03/12 10:56:48 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)ex_vmain.c 7.7 (Berkeley) 6/7/85"; #endif not lint *************** *** 112,118 **** if (trace) fprintf(trace, "pc=%c",peekkey()); #endif ! if (isdigit(peekkey()) && peekkey() != '0') { hadcnt = 1; cnt = vgetcnt(); forbid (cnt <= 0); --- 120,128 ---- if (trace) fprintf(trace, "pc=%c",peekkey()); #endif ! if (isascii(peekkey()) && ! isdigit(peekkey()) && ! peekkey() != '0') { hadcnt = 1; cnt = vgetcnt(); forbid (cnt <= 0); *************** *** 126,132 **** * an 'empty' named buffer spec in the routine * kshift (see ex_temp.c). */ ! forbid (c == '0' || !isalpha(c) && !isdigit(c)); vreg = c; } reread: --- 136,143 ---- * an 'empty' named buffer spec in the routine * kshift (see ex_temp.c). */ ! forbid (c == '0' || ! isascii(c) && !isalpha(c) && !isdigit(c)); vreg = c; } reread: *************** *** 158,164 **** * to go back to the "for" to interpret it. Likewise * for a buffer name. */ ! if ((isdigit(c) && c!='0') || c == '"') { ungetkey(c); goto looptop; } --- 169,175 ---- * to go back to the "for" to interpret it. Likewise * for a buffer name. */ ! if ((isascii(c) && isdigit(c) && c!='0') || c == '"') { ungetkey(c); goto looptop; } Index: ucb/ex/ex_voper.c *** /tmp/,RCSt1014242 Sat Mar 12 10:58:08 1988 --- ex_voper.c Sat Mar 12 10:57:00 1988 *************** *** 1,5 **** --- 1,13 ---- /* * $Log: ex_voper.c,v $ + * Revision 1.3 88/03/12 10:56:56 gww + * Correct guard against non-ascii index of _ctype_[]. Thanks to + * Keith Bostic (bostic@ucbvax). + * + * Revision 1.2 87/05/08 17:08:08 gww + * Check for ATTN (-2) before using isxxxx macro so as not to negatively + * index _ctype_[] and possibly get a segment fault. + * * Revision 1.1 86/12/23 18:16:15 gww * Initial revision * *************** *** 11,17 **** */ #ifndef lint ! static char *ERcsId = "$Header: ex_voper.c,v 1.1 86/12/23 18:16:15 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)ex_voper.c 7.4 (Berkeley) 6/7/85"; #endif not lint --- 19,25 ---- */ #ifndef lint ! static char *ERcsId = "$Header: ex_voper.c,v 1.3 88/03/12 10:56:56 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)ex_voper.c 7.4 (Berkeley) 6/7/85"; #endif not lint *************** *** 133,139 **** * Had an operator, so accept another count. * Multiply counts together. */ ! if (isdigit(peekkey()) && peekkey() != '0') { cnt *= vgetcnt(); Xcnt = cnt; forbid (cnt <= 0); --- 141,147 ---- * Had an operator, so accept another count. * Multiply counts together. */ ! if (isascii(peekkey()) && isdigit(peekkey()) && peekkey() != '0') { cnt *= vgetcnt(); Xcnt = cnt; forbid (cnt <= 0);