open-src/lib/libXext/sun-src/src/XPanoramiX.c
changeset 1345 d5dacbb8de2b
parent 943 294f64612d23
--- a/open-src/lib/libXext/sun-src/src/XPanoramiX.c	Wed May 01 12:27:46 2013 -0700
+++ b/open-src/lib/libXext/sun-src/src/XPanoramiX.c	Wed May 15 13:44:02 2013 -0700
@@ -26,7 +26,7 @@
 Equipment Corporation.
 
 ******************************************************************/
-/* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -648,23 +648,37 @@
 	return NULL;
     }
 
-    if(rep.number) {
-	if((scrnInfo = Xmalloc(sizeof(XineramaScreenInfo) * rep.number))) {
-	    xXineramaScreenInfo scratch;
-	    int i;
+    /*
+     * rep.number is a CARD32 so could be as large as 2^32
+     * The X11 protocol limits the total screen size to 64k x 64k,
+     * and no screen can be smaller than a pixel.  While technically
+     * that means we could theoretically reach 2^32 screens, and that's
+     * not even taking overlap into account, Xorg is currently limited
+     * to 16 screens, and few known servers have a much higher limit,
+     * so 1024 seems more than enough to prevent both integer overflow
+     * and insane X server responses causing massive memory allocation.
+     */
+    if ((rep.number > 0) && (rep.number <= 1024))
+	scrnInfo = Xmalloc(sizeof(XineramaScreenInfo) * rep.number);
+    if (scrnInfo != NULL) {
+	int i;
 
-	    for(i = 0; i < rep.number; i++) {
-		_XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo);
-		scrnInfo[i].screen_number = i;
-		scrnInfo[i].x_org 	  = scratch.x_org;
-		scrnInfo[i].y_org 	  = scratch.y_org;
-		scrnInfo[i].width 	  = scratch.width;
-		scrnInfo[i].height 	  = scratch.height;
-	    }
+	for (i = 0; i < rep.number; i++) {
+	    xXineramaScreenInfo scratch;
+
+	    _XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo);
 
-	    *number = rep.number;
-	} else
-	    _XEatData(dpy, rep.length << 2);
+	    scrnInfo[i].screen_number = i;
+	    scrnInfo[i].x_org	= scratch.x_org;
+	    scrnInfo[i].y_org	= scratch.y_org;
+	    scrnInfo[i].width	= scratch.width;
+	    scrnInfo[i].height	= scratch.height;
+	}
+
+	*number = rep.number;
+    } else {
+	_XEatDataWords(dpy, rep.length);
+	*number = 0;
     }
 
     UnlockDisplay (dpy);