various adict fixes - reduce memory leaks, - don't write beyond the end of buffers, etc. - apply akumar's patch from Fri Jan 16 2009 9fans email Les Misérables but in a more complete form. - fix crashes on mips (stack too small) Reference: /n/atom/patch/applied/adictfixes Date: Fri Feb 28 12:23:18 CET 2014 Signed-off-by: quanstro@quanstro.net --- /acme/bin/source/adict/adict.c Fri Feb 28 12:21:52 2014 +++ /acme/bin/source/adict/adict.c Fri Feb 28 12:21:52 2014 @@ -7,7 +7,7 @@ enum { - STACK = 8192, + STACK = 2*8192, }; char *prog = "adict"; @@ -27,8 +27,8 @@ void usage(void) { - fprint(2, "usage: %s [-d dictname] [pattern]\n", argv0); - threadexitsall(nil); + fprint(2, "usage: %s [-d dictname] [pattern]\n", argv0); + threadexitsall(nil); } int mainstacksize = STACK; @@ -38,7 +38,7 @@ { ARGBEGIN{ case 'd': - dict = strdup(ARGF()); + dict = strdup(EARGF(usage())); break; default: usage(); @@ -110,8 +110,7 @@ int fd, i; Biobuf inbuf; - char *bufptr; -char *obuf; + char *bufptr, *p; if (pattern == nil) { curone = nil; @@ -120,23 +119,28 @@ return 0; } - sprint(buffer,"/%s/A", pattern); + snprint(buffer, sizeof buffer, "/%s/A", pattern); fd = procrexec(xprog, "-d", dict, "-c", buffer, nil); Binit(&inbuf, fd, OREAD); - i = 0; curindex = 0; - while ((bufptr = Brdline(&inbuf, '\n')) != nil && (i < (MAXMATCH-1))) { + curone = nil; + for(i = 0; i < nelem(curaddr); i++){ + free(curaddr[i]); + curaddr[i] = nil; + } + for(i = 0; i < nelem(curaddr)-1;){ + if((bufptr = Brdline(&inbuf, '\n')) == nil) + break; bufptr[Blinelen(&inbuf)-1] = 0; -obuf=bufptr; - while (bufptr[0] != '#' && bufptr[0] != 0) bufptr++; -if(bufptr[0] == 0) - print("whoops buf «%s»\n", obuf); - curaddr[i] = malloc(strlen(bufptr)); - strcpy(curaddr[i], bufptr); - i++; + p = strchr(bufptr, '#'); + if(p == nil){ + print("whoops buf «%s»\n", bufptr); + continue; + } + curaddr[i++] = strdup(p); } - curaddr[i] = nil; - if (i == MAXMATCH) + curaddr[i++] = nil; + if (i == nelem(curaddr)) fprint(2, "Too many matches!\n"); Bterm(&inbuf); close(fd); @@ -149,24 +153,20 @@ getpattern(char *addr) { /* Get the pattern corresponding to an absolute address.*/ - int fd; - char *res, *t; + int fd, n; + char *res, c; - res = nil; - sprint(buffer,"%sh", addr); + res = ""; + snprint(buffer, sizeof buffer, "%sh", addr); fd = procrexec(xprog, "-d", dict, "-c", buffer, nil); - if (read(fd, pbuffer, 80) > 80) - fprint(2, "Error in getting addres from dict.\n"); + if ((n = read(fd, pbuffer, sizeof pbuffer-1)) < 1) + fprint(2, "Error in getting address from dict.\n"); else { - t = pbuffer; /* remove trailing whitespace, newline */ - if (t != nil){ - while(*t != 0 && *t != '\n') - t++; - if(t == 0 && t > pbuffer) - t--; - while(t >= pbuffer && (*t==' ' || *t=='\n' || *t=='\t' || *t=='\r')) - *t-- = 0; + while(n>0){ + c = pbuffer[--n]; + if(memchr(" \n\t\r", c, 5) == nil) + break; } res = pbuffer; } @@ -179,23 +179,22 @@ { /* Increment or decrement the current address (curone). */ - int fd; + int fd, n; char *res, *t; res = nil; if (dir < 0) - sprint(buffer,"%s-a", curone); + snprint(buffer, sizeof buffer, "%s-a", curone); else - sprint(buffer,"%s+a", curone); + snprint(buffer, sizeof buffer, "%s+a", curone); fd = procrexec(xprog, "-d", dict, "-c", buffer, nil); - if (read(fd, abuffer, 80) > 80) - fprint(2, "Error in getting addres from dict.\n"); + if ((n = read(fd, abuffer, sizeof abuffer-1)) < 1) + fprint(2, "Error in getting address from dict.\n"); else { - res = abuffer; - while (*res != '#') res++; - t = res; - while ((*t != '\n') && (t != nil)) t++; - if (t != nil) *t = 0; + res[n] = 0; + res = strchr(abuffer, '#'); + if(res != nil && (t = strchr(res, '\n')) != nil) + *t = 0; } close(fd); return(res); @@ -238,13 +237,13 @@ if (curone == nil) { if (pattern != nil) { - sprint(buf,"Pattern not found.\n"); + snprint(buf, sizeof buf, "Pattern not found.\n"); wwritebody(cwin, buf, 19); wclean(cwin); } return; } - sprint(buffer,"%sp", curone); + snprint(buffer, sizeof buffer, "%sp", curone); fd = procrexec(xprog, "-d", dict, "-c", buffer, nil); wreplace(cwin, "0,$","",0); /* Clear window */ while ((nb = read(fd, buf, BUFSIZE)) > 0) { @@ -262,7 +261,7 @@ int fd, nb; char buf[BUFSIZE]; - sprint(buffer,"/%s/H", pattern); + snprint(buffer, sizeof buffer, "/%s/H", pattern); fd = procrexec(xprog, "-d", dict, "-c", buffer, nil); while ((nb = read(fd, buf, BUFSIZE)) > 0) wwritebody(cwin, buf, nb); @@ -273,44 +272,26 @@ char* format(char *s) { - /* Format a string to be written in window tag. Acme doesn't like */ - /* non alpha-num's in the tag line. */ - - char *t, *h; - - t = fbuffer; - if (s == nil) { - *t = 0; - return t; - } - strcpy(t, s); - h = t; - while (*t != 0) { - if (!(((*t >= 'a') && (*t <= 'z')) || - ((*t >= 'A') && (*t <= 'Z')) || - ((*t >= '0') && (*t <= '9')))) - *t = '_'; - t++; - } - if (strlen(h) > MAXTAG) - h[MAXTAG] = 0; - if (strcmp(s,h) == 0) return s; - return h; + if(s == nil) + return ""; + return s; } void openwin(char *name, char *buttons, Win *twin, int wintype) { - char buf[80]; + char buf[80], *p; wnew(twin); if (wintype == Dictwin) - sprint(buf,"%s",name); - else + snprint(buf, sizeof buf, "%s",name); + else{ + p = format(pattern); if ((wintype == Entrywin) && (count > 1)) - sprint(buf,"%s/%s/%s/%d",name, dict, format(pattern), curindex+1); + snprint(buf, sizeof buf, "%s/%s/%.20s/%d", name, dict, p, curindex+1); else - sprint(buf,"%s/%s/%s",name, dict, format(pattern)); + snprint(buf, sizeof buf, "%s/%s/%.20s", name, dict, p); + } wname(twin, buf); wtagwrite(twin, buttons, strlen(buttons)); wclean(twin); @@ -340,7 +321,7 @@ name = arg[0]; buttons = arg[1]; twin = arg[2]; - wintype = (int)arg[3]; + wintype = (int)(uintptr)arg[3]; sendul(arg[4], 0); openwin(name, buttons, twin, wintype); @@ -430,7 +411,7 @@ /* Kill all processes related to this one. */ int fd; - sprint(buffer, "/proc/%d/notepg", getpid()); + snprint(buffer, sizeof buffer, "/proc/%d/notepg", getpid()); fd = open(buffer, OWRITE); rfork(RFNOTEG); write(fd, "kill", 4); @@ -439,7 +420,7 @@ int command(char *com, Win *w, int wintype) { - char *buf; + char *p; if (strncmp(com, "Del", 3) == 0) { switch(wintype){ @@ -468,8 +449,8 @@ if (strncmp(com, "Next", 4) == 0){ if (curone != nil) { curone = chgaddr(1); - buf = getpattern(curone); - sprint(buffer,"%s/%s/%s", prog, dict, format(buf)); + p = format(getpattern(curone)); + snprint(buffer, sizeof buffer, "%s/%s/%.20s", prog, dict, p); wname(w, buffer); dispentry(w); } @@ -478,8 +459,8 @@ if (strncmp(com, "Prev",4) == 0){ if (curone != nil) { curone = chgaddr(-1); - buf = getpattern(curone); - sprint(buffer,"%s/%s/%s", prog, dict, format(buf)); + p = format(getpattern(curone)); + snprint(buffer, sizeof buffer, "%s/%s/%.20s", prog, dict, p); wname(w, buffer); dispentry(w); } @@ -490,7 +471,8 @@ curindex = 0; curone = curaddr[curindex]; if (curone != nil) { - sprint(buffer,"%s/%s/%s/%d",prog,dict,format(pattern),curindex+1); + p = format(pattern); + snprint(buffer, sizeof buffer, "%s/%s/%.20s/%d", prog, dict, p, curindex+1); wname(w, buffer); dispentry(w); } @@ -500,92 +482,81 @@ } void -handle(Win *w, int wintype) +handle1(Win *w, int wintype) { Event e, e2, ea, etoss; - char *s, *t, buf[80]; - int tmp, na; + char *s, buf[80]; + int i, na; - while (True) { - wevent(w, &e); - switch(e.c2){ - default: - /* fprint(2,"unknown message %c%c\n", e.c1, e.c2); */ - break; - case 'i': - /* fprint(2,"'%s' inserted in tag at %d\n", e.b, e.q0);*/ - break; - case 'I': - /* fprint(2,"'%s' inserted in body at %d\n", e.b, e.q0);*/ - break; - case 'd': - /* fprint(2, "'%s' deleted in tag at %d\n", e.b, e.q0);*/ - break; - case 'D': - /* fprint(2, "'%s' deleted in body at %d\n", e.b, e.q0);*/ - break; - case 'x': - case 'X': /* Execute command. */ - if (e.flag & 2) - wevent(w, &e2); - if(e.flag & 8){ - wevent(w, &ea); - wevent(w, &etoss); - na = ea.nb; - } else - na = 0; - s = e.b; - if ((e.flag & 2) && e.nb == 0) - s = e2.b; - if(na){ - t = malloc(strlen(s)+1+na+1); - snprint(t, strlen(s)+1+na+1, "%s %s", s, ea.b); - s = t; - } - /* if it's a long message, it can't be for us anyway */ - if(!command(s, w, wintype)) /* send it back */ - wwriteevent(w, &e); - if(na) - free(s); - break; - case 'l': - case 'L': /* Look for something. */ - if (e.flag & 2) - wevent(w, &e); - wclean(w); /* Set clean bit. */ - if (wintype == Dictwin) { - strcpy(buf, e.b); - args[0] = lprog; - args[1] = "-d"; - args[2] = buf; - args[3] = nil; - procpexec(lprog, args); /* New adict with chosen dict. */ - } - if (wintype == Entrywin) { - strcpy(buf, e.b); - args[0] = lprog; - args[1] = "-d"; - args[2] = dict; - args[3] = buf; - args[4] = nil; - procpexec(lprog, args); /* New adict with chosen pattern. */ - } - if (wintype == Matchwin) { - tmp = atoi(e.b) - 1; - if ((tmp >= 0) && (tmp < MAXMATCH) && (curaddr[tmp] != nil)) { - curindex = tmp; - curone = curaddr[curindex]; - /* Display selected match. */ - if (Eopen) { - sprint(buf,"%s/%s/%s/%d",prog,dict,format(pattern),curindex+1); - wname(&Ewin, buf); - dispentry(&Ewin); - } - else - procopenwin(prog,"Nmatch Prev Next", &Ewin, Entrywin); - } + wevent(w, &e); + switch(e.c2){ + default: + break; + case 'x': + case 'X': /* Execute command. */ + if (e.flag & 2) + wevent(w, &e2); + if(e.flag & 8){ + wevent(w, &ea); + wevent(w, &etoss); + na = ea.nb; + } else + na = 0; + s = e.b; + if ((e.flag & 2) && e.nb == 0) + s = e2.b; + if(na) + s = smprint("%s %s", s, ea.b); + /* if it's a long message, it can't be for us anyway */ + if(!command(s, w, wintype)) /* send it back */ + wwriteevent(w, &e); + if(na) + free(s); + break; + case 'l': + case 'L': /* Look for something. */ + if (e.flag & 2) + wevent(w, &e); + wclean(w); /* Set clean bit. */ + if (wintype == Dictwin) { + strcpy(buf, e.b); + args[0] = lprog; + args[1] = "-d"; + args[2] = buf; + args[3] = nil; + procpexec(lprog, args); /* New adict with chosen dict. */ + } + if (wintype == Entrywin) { + strcpy(buf, e.b); + args[0] = lprog; + args[1] = "-d"; + args[2] = dict; + args[3] = buf; + args[4] = nil; + procpexec(lprog, args); /* New adict with chosen pattern. */ + } + if (wintype == Matchwin) { + i = atoi(e.b) - 1; + if(i < 0 || i >= nelem(curaddr) || curaddr[i] == nil) + break; + curindex = i; + curone = curaddr[curindex]; + /* Display selected match. */ + if (Eopen) { + snprint(buf, sizeof buf, "%s/%s/%s/%d", prog, dict, pattern, curindex+1); + wname(&Ewin, buf); + dispentry(&Ewin); } - break; + else + procopenwin(prog,"Nmatch Prev Next", &Ewin, Entrywin); } + break; } +} + +void +handle(Win *w, int wintype) +{ + for(;;) + handle1(w, wintype); } --- /acme/bin/source/adict/adict.h Fri Feb 28 12:21:53 2014 +++ /acme/bin/source/adict/adict.h Fri Feb 28 12:21:53 2014 @@ -5,6 +5,5 @@ Dictwin }; -#define MAXTAG 20 #define MAXMATCH 100 #define BUFSIZE 4096