1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

edit: avoid potential crash with overlapping strings

In vi.c, there is a potential use of strcpy(3) on overlapping
strings, which is undefined behaviour:

> 	SHOPT_MULTIBYTE == 0
>
> 	# define gencpy(a,b)  strcpy((char*)(a),(char*)(b))
>
> 		.
> 		.
> 		.
>
> 	if( mode != 'y' )
> 	{
> 		gencpy(cp,cp+nchars);

Thanks to Heiko Berges for the report.

src/cmd/ksh93/edit/{edit,emacs,vi}.c:
- Change almost all use of strcpy(3) to libast strcopy(), which
  is a simple implementation that does not have a problem with
  overlapping strings. Note that the return value is different
  (it returns a pointer to the terminating '\0') but that is not
  relevant in any of these cases.
- Same for strncpy(3) => libast strncopy().

src/lib/libast/string/strcopy.c:
- Backport a couple of cosmetic tweaks from the 93v- beta.
This commit is contained in:
Martijn Dekker 2022-04-21 02:34:33 +02:00
parent 41db60c6be
commit b52edb380c
5 changed files with 20 additions and 19 deletions

View file

@ -772,7 +772,7 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
register int shift = 7-ep->e_wsize; register int shift = 7-ep->e_wsize;
ep->e_wsize = 7; ep->e_wsize = 7;
pp = ep->e_prompt+1; pp = ep->e_prompt+1;
strcpy(pp,pp+shift); strcopy(pp,pp+shift);
ep->e_plen -= shift; ep->e_plen -= shift;
last[-ep->e_plen-2] = '\r'; last[-ep->e_plen-2] = '\r';
} }
@ -819,11 +819,11 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
#error no tput method #error no tput method
#endif #endif
if((pp = nv_getval(SH_SUBSCRNOD)) && strlen(pp) < sizeof(CURSOR_UP)) if((pp = nv_getval(SH_SUBSCRNOD)) && strlen(pp) < sizeof(CURSOR_UP))
strcpy(CURSOR_UP,pp); strcopy(CURSOR_UP,pp);
else else
CURSOR_UP[0] = '\0'; /* no escape sequence is better than a faulty one */ CURSOR_UP[0] = '\0'; /* no escape sequence is better than a faulty one */
nv_unset(SH_SUBSCRNOD); nv_unset(SH_SUBSCRNOD);
strcpy(ep->e_termname,term); strcopy(ep->e_termname,term);
sh.options = o; sh.options = o;
sigrelease(SIGINT); sigrelease(SIGINT);
} }
@ -1493,7 +1493,7 @@ int ed_external(const genchar *src, char *dest)
#ifdef _lib_wcscpy #ifdef _lib_wcscpy
wcscpy((wchar_t *)dest,(const wchar_t *)buffer); wcscpy((wchar_t *)dest,(const wchar_t *)buffer);
#else #else
strcpy(dest,buffer); strcopy(dest,buffer);
#endif #endif
return(c); return(c);
} }
@ -1662,7 +1662,7 @@ static int keytrap(Edit_t *ep,char *inbuff,register int insize, int bufsize, int
nv_unset(ED_CHRNOD); nv_unset(ED_CHRNOD);
else if(bufsize>0) else if(bufsize>0)
{ {
strncpy(inbuff,cp,bufsize); strncopy(inbuff,cp,bufsize);
inbuff[bufsize-1]='\0'; inbuff[bufsize-1]='\0';
insize = strlen(inbuff); insize = strlen(inbuff);
} }

View file

@ -90,8 +90,8 @@ One line screen editor for any program
# define digit(c) ((c&~STRIP)==0 && isdigit(c)) # define digit(c) ((c&~STRIP)==0 && isdigit(c))
#else #else
# define gencpy(a,b) strcpy((char*)(a),(char*)(b)) # define gencpy(a,b) strcopy((char*)(a),(char*)(b))
# define genncpy(a,b,n) strncpy((char*)(a),(char*)(b),n) # define genncpy(a,b,n) strncopy((char*)(a),(char*)(b),n)
# define genlen(str) strlen(str) # define genlen(str) strlen(str)
# define print(c) isprint(c) # define print(c) isprint(c)
# define isword(c) (isalnum(out[c]) || (out[c]=='_')) # define isword(c) (isalnum(out[c]) || (out[c]=='_'))
@ -1425,7 +1425,7 @@ static void search(Emacs_t* ep,genchar *out,int direction)
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
ed_external(string,(char*)string); ed_external(string,(char*)string);
#endif /* SHOPT_MULTIBYTE */ #endif /* SHOPT_MULTIBYTE */
strncpy(lstring,((char*)string)+2,SEARCHSIZE-1); strncopy(lstring,((char*)string)+2,SEARCHSIZE-1);
lstring[SEARCHSIZE-1] = 0; lstring[SEARCHSIZE-1] = 0;
ep->prevdirection = direction; ep->prevdirection = direction;
} }

View file

@ -1057,7 +1057,7 @@ char *hist_word(char *string,int size,int word)
*cp = 0; *cp = 0;
if(s1 != string) if(s1 != string)
/* We can't use strcpy() because the two buffers may overlap. */ /* We can't use strcpy() because the two buffers may overlap. */
memmove(string,s1,strlen(s1)+1); strcopy(string,s1);
return(string); return(string);
} }

View file

@ -67,8 +67,8 @@
# define isalph(v) _isalph(virtual[v]) # define isalph(v) _isalph(virtual[v])
#else #else
static genchar _c; static genchar _c;
# define gencpy(a,b) strcpy((char*)(a),(char*)(b)) # define gencpy(a,b) strcopy((char*)(a),(char*)(b))
# define genncpy(a,b,n) strncpy((char*)(a),(char*)(b),n) # define genncpy(a,b,n) strncopy((char*)(a),(char*)(b),n)
# define genlen(str) strlen(str) # define genlen(str) strlen(str)
# define isalph(v) ((_c=virtual[v])=='_'||isalnum(_c)) # define isalph(v) ((_c=virtual[v])=='_'||isalnum(_c))
# undef isblank # undef isblank
@ -908,7 +908,7 @@ static int cntlmode(Vi_t *vp)
hist_copy((char*)virtual, MAXLINE, curhline,-1); hist_copy((char*)virtual, MAXLINE, curhline,-1);
else else
{ {
strcpy((char*)virtual,(char*)vp->u_space); strcopy((char*)virtual,(char*)vp->u_space);
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
ed_internal((char*)vp->u_space,vp->u_space); ed_internal((char*)vp->u_space,vp->u_space);
#endif /* SHOPT_MULTIBYTE */ #endif /* SHOPT_MULTIBYTE */
@ -1634,7 +1634,7 @@ static int mvcursor(register Vi_t* vp,register int motion)
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
ed_external(virtual,lsearch+1); ed_external(virtual,lsearch+1);
#else #else
strcpy(lsearch+1,virtual); strcopy(lsearch+1,virtual);
#endif /* SHOPT_MULTIBYTE */ #endif /* SHOPT_MULTIBYTE */
*lsearch = '^'; *lsearch = '^';
vp->direction = -2; vp->direction = -2;
@ -2362,7 +2362,7 @@ static int search(register Vi_t* vp,register int mode)
{ {
/*** user wants repeat of last search ***/ /*** user wants repeat of last search ***/
del_line(vp,BAD); del_line(vp,BAD);
strcpy( ((char*)virtual)+1, lsearch); strcopy( ((char*)virtual)+1, lsearch);
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
*((char*)virtual) = '/'; *((char*)virtual) = '/';
ed_internal((char*)virtual,virtual); ed_internal((char*)virtual,virtual);
@ -2394,7 +2394,7 @@ static int search(register Vi_t* vp,register int mode)
location = hist_find(sh.hist_ptr,((char*)virtual)+1, curhline, 1, new_direction); location = hist_find(sh.hist_ptr,((char*)virtual)+1, curhline, 1, new_direction);
} }
cur_virt = i; cur_virt = i;
strncpy(lsearch, ((char*)virtual)+1, SEARCHSIZE-1); strncopy(lsearch, ((char*)virtual)+1, SEARCHSIZE-1);
lsearch[SEARCHSIZE-1] = 0; lsearch[SEARCHSIZE-1] = 0;
if( (curhline=location.hist_command) >=0 ) if( (curhline=location.hist_command) >=0 )
{ {

View file

@ -1,8 +1,8 @@
/*********************************************************************** /***********************************************************************
* * * *
* This software is part of the ast package * * This software is part of the ast package *
* Copyright (c) 1985-2011 AT&T Intellectual Property * * Copyright (c) 1985-2012 AT&T Intellectual Property *
* Copyright (c) 2020-2021 Contributors to ksh 93u+m * * Copyright (c) 2020-2022 Contributors to ksh 93u+m *
* and is licensed under the * * and is licensed under the *
* Eclipse Public License, Version 1.0 * * Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property * * by AT&T Intellectual Property *
@ -30,7 +30,8 @@
char* char*
strcopy(register char* s, register const char* t) strcopy(register char* s, register const char* t)
{ {
if (!t) return(s); if (!t)
return s;
while (*s++ = *t++); while (*s++ = *t++);
return(--s); return s - 1;
} }