ref: df7fcc6cac30738852965d9f4c1b6e90c6a977ae
parent: c0d21d35b103e980e658fff1ef07107e72a03364
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Nov 7 17:01:18 EST 2018
libdraw: fix gengetwindow() - fix fd leak in winname read() <= 0 case - avoid freeing d->image (was by freeimage((*scrp)->image)) - dont leak screen and window in fullscreen mode
--- a/sys/src/libdraw/init.c
+++ b/sys/src/libdraw/init.c
@@ -127,12 +127,9 @@
retry:
fd = open(winname, OREAD);
if(fd<0 || (n=read(fd, buf, sizeof buf-1))<=0){
- if((image=d->image) == nil){
- *winp = nil;
- d->screenimage = nil;
- return -1;
- }
+ if(fd >= 0) close(fd);
strcpy(buf, "noborder");
+ image = d->image;
}else{
close(fd);
buf[n] = '\0';
@@ -148,37 +145,40 @@
goto retry;
}
}
- if(*winp != nil){
- _freeimage1(*winp);
+ }
+ if(*winp != nil){
+ _freeimage1(*winp);
+ if((*scrp)->image != nil
+ && (*scrp)->image != image
+ && (*scrp)->image != d->image)
freeimage((*scrp)->image);
- freescreen(*scrp);
- *scrp = nil;
- }
- if(image == nil){
- *winp = nil;
- d->screenimage = nil;
- return -1;
- }
+ freescreen(*scrp);
+ *scrp = nil;
}
-
+ if(image == nil){
+ *winp = nil;
+ d->screenimage = nil;
+ return -1;
+ }
d->screenimage = image;
*scrp = allocscreen(image, d->white, 0);
if(*scrp == nil){
*winp = nil;
d->screenimage = nil;
- freeimage(image);
+ if(image != d->image)
+ freeimage(image);
return -1;
}
-
r = image->r;
if(strncmp(buf, "noborder", 8) != 0)
- r = insetrect(image->r, Borderwidth);
+ r = insetrect(r, Borderwidth);
*winp = _allocwindow(*winp, *scrp, r, ref, DWhite);
if(*winp == nil){
freescreen(*scrp);
*scrp = nil;
d->screenimage = nil;
- freeimage(image);
+ if(image != d->image)
+ freeimage(image);
return -1;
}
d->screenimage = *winp;