From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Chong Yidong Newsgroups: gmane.emacs.devel Subject: Re: image size limit? Date: Sun, 16 Oct 2005 18:27:54 -0400 Message-ID: <87hdbht7v9.fsf@stupidchicken.com> References: <87oe5v7q19.fsf@stupidchicken.com> <87k6giiqh3.fsf@pacem.orebokech.com> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1129501741 19306 80.91.229.2 (16 Oct 2005 22:29:01 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sun, 16 Oct 2005 22:29:01 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 17 00:29:00 2005 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1ERGz9-0003pK-E4 for ged-emacs-devel@m.gmane.org; Mon, 17 Oct 2005 00:28:07 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ERGz8-0008DV-Px for ged-emacs-devel@m.gmane.org; Sun, 16 Oct 2005 18:28:06 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1ERGyy-0008DO-PY for emacs-devel@gnu.org; Sun, 16 Oct 2005 18:27:56 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1ERGyy-0008DC-4F for emacs-devel@gnu.org; Sun, 16 Oct 2005 18:27:56 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1ERGyx-0008D9-Vq for emacs-devel@gnu.org; Sun, 16 Oct 2005 18:27:56 -0400 Original-Received: from [18.95.6.192] (helo=localhost.localdomain) by monty-python.gnu.org with esmtp (Exim 4.34) id 1ERGyx-0004lA-Bu; Sun, 16 Oct 2005 18:27:55 -0400 Original-Received: by localhost.localdomain (Postfix, from userid 1000) id 0C7581E42B7; Sun, 16 Oct 2005 18:27:54 -0400 (EDT) Original-To: rms@gnu.org In-Reply-To: (Richard M. Stallman's message of "Thu, 13 Oct 2005 16:13:31 -0400") User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:44150 Archived-At: Ok, I figured out how to do it. This patch imposes height and width limits based on the variable max-image-size. It should cause load_gif and the other image loading functions to return before the third-party libraries are called upon to load the image data, so we shouldn't get memory-overallocation at any point. I've tested it for png, jpeg, tiff, and gif. It should work for xbm, pbm and ghostscript, but I haven't checked. It doesn't impose limits on xpm images, because I don't understand the xpm code too well. If no one objects to this, I'll install it sometime next week. *** emacs/src/image.c.~1.36.~ 2005-10-11 11:09:35.000000000 -0400 --- emacs/src/image.c 2005-10-16 18:10:45.000000000 -0400 *************** *** 1097,1102 **** --- 1097,1105 ---- Image type independent image structures ***********************************************************************/ + #define MAX_IMAGE_SIZE 100000 + EMACS_INT Vmax_image_size; + static struct image *make_image P_ ((Lisp_Object spec, unsigned hash)); static void free_image P_ ((struct frame *f, struct image *img)); *************** *** 1708,1713 **** --- 1711,1722 ---- if (img->hash == hash && !NILP (Fequal (img->spec, spec))) break; + if (img && img->load_failed_p) + { + free_image (f, img); + img = NULL; + } + /* If not found, create a new image and cache it. */ if (img == NULL) { *************** *** 2992,2998 **** expect (XBM_TK_NUMBER); } ! if (*width < 0 || *height < 0) goto failure; else if (data == NULL) goto success; --- 3001,3008 ---- expect (XBM_TK_NUMBER); } ! if (*width <= 0 || *width > Vmax_image_size ! || *height <= 0 || *height > Vmax_image_size) goto failure; else if (data == NULL) goto success; *************** *** 5465,5472 **** max_color_idx = 255; } ! if (width < 0 ! || height < 0 || (type != PBM_MONO && max_color_idx < 0)) goto error; --- 5475,5482 ---- max_color_idx = 255; } ! if (width <= 0 || width > Vmax_image_size ! || height <=0 || height > Vmax_image_size || (type != PBM_MONO && max_color_idx < 0)) goto error; *************** *** 5966,5971 **** --- 5976,5985 ---- fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + if (width <= 0 || width > Vmax_image_size + || height <=0 || height > Vmax_image_size) + goto error; + /* If image contains simply transparency data, we prefer to construct a clipping mask. */ if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) *************** *** 6726,6731 **** --- 6740,6752 ---- width = img->width = cinfo.output_width; height = img->height = cinfo.output_height; + if (width <= 0 || width > Vmax_image_size + || height <=0 || height > Vmax_image_size) + { + image_error ("Invalid image size", Qnil, Qnil); + longjmp (mgr.setjmp_buffer, 2); + } + /* Create X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) longjmp (mgr.setjmp_buffer, 2); *************** *** 7155,7160 **** --- 7176,7189 ---- of width x height 32-bit values. */ fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); + if (width <= 0 || width > Vmax_image_size + || height <=0 || height > Vmax_image_size) + { + image_error ("Invalid image size", Qnil, Qnil); + UNGCPRO; + return 0; + } + buf = (uint32 *) xmalloc (width * height * sizeof *buf); rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); *************** *** 7459,7464 **** --- 7488,7504 ---- } } + /* Abort if the stated image size is too big, before reading entire + contents. */ + if (gif->SWidth <= 0 || gif->SWidth > Vmax_image_size + || gif->SHeight <=0 || gif->SHeight > Vmax_image_size) + { + image_error ("Invalid image size", Qnil, Qnil); + fn_DGifCloseFile (gif); + UNGCPRO; + return 0; + } + /* Read entire contents. */ rc = fn_DGifSlurp (gif); if (rc == GIF_ERROR) *************** *** 7492,7497 **** --- 7532,7546 ---- max (gif->Image.Top + gif->Image.Height, image_top + image_height)); + if (width <= 0 || width > Vmax_image_size + || height <=0 || height > Vmax_image_size) + { + image_error ("Invalid image size", Qnil, Qnil); + fn_DGifCloseFile (gif); + UNGCPRO; + return 0; + } + /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) { *************** *** 7944,7949 **** --- 7993,8005 ---- in_height = XFASTINT (pt_height) / 72.0; img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; + if (img->width <= 0 || img->width > Vmax_image_size + || img->height <=0 || img->height > Vmax_image_size) + { + image_error ("Invalid image size", Qnil, Qnil); + return 0; + } + /* Create the pixmap. */ xassert (img->pixmap == NO_PIXMAP); *************** *** 8217,8222 **** --- 8273,8286 ---- Vimage_library_alist = Qnil; Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt); + DEFVAR_INT ("max-image-size", &Vmax_image_size, + doc: /* Maximum width and height, in pixels, that an image can have. + + Emacs will not load an image into memory if its width or height, in + pixels, is larger than this value. Additional limits may be imposed + by the external libraries that Emacs uses to read the images. */); + Vmax_image_size = MAX_IMAGE_SIZE; + Vimage_type_cache = Qnil; staticpro (&Vimage_type_cache);