Pārlūkot izejas kodu

Linux/X11: Fix memory leak from created screen images

Allocated XImages are improperly free'd with XFree.
The X11 documentation says that XImage should use
XDestroyImage to free both the image structure and
the data pointed to by the image structure.

Also fix a potential use-after-free bug.
Ronald Casili 1 gadu atpakaļ
vecāks
revīzija
3636d9dafc
1 mainītis faili ar 5 papildinājumiem un 4 dzēšanām
  1. 5 4
      platform/linuxbsd/x11/display_server_x11.cpp

+ 5 - 4
platform/linuxbsd/x11/display_server_x11.cpp

@@ -1519,7 +1519,7 @@ Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const {
 			if (image) {
 			if (image) {
 				XColor c;
 				XColor c;
 				c.pixel = XGetPixel(image, 0, 0);
 				c.pixel = XGetPixel(image, 0, 0);
-				XFree(image);
+				XDestroyImage(image);
 				XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c);
 				XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c);
 				color = Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0);
 				color = Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0);
 				break;
 				break;
@@ -1637,11 +1637,12 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
 				}
 				}
 			}
 			}
 		} else {
 		} else {
-			XFree(image);
-			ERR_FAIL_V_MSG(Ref<Image>(), vformat("XImage with RGB mask %x %x %x and depth %d is not supported.", (uint64_t)image->red_mask, (uint64_t)image->green_mask, (uint64_t)image->blue_mask, (int64_t)image->bits_per_pixel));
+			String msg = vformat("XImage with RGB mask %x %x %x and depth %d is not supported.", (uint64_t)image->red_mask, (uint64_t)image->green_mask, (uint64_t)image->blue_mask, (int64_t)image->bits_per_pixel);
+			XDestroyImage(image);
+			ERR_FAIL_V_MSG(Ref<Image>(), msg);
 		}
 		}
 		img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data);
 		img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, img_data);
-		XFree(image);
+		XDestroyImage(image);
 	}
 	}
 
 
 	return img;
 	return img;