[U-Boot] [PATCH] cmd_bmp: fix very long uncompressing time of gzipped bitmaps

Anatolij Gustschin agust at denx.de
Tue Jul 19 14:12:43 CEST 2011


If a compressed bitmap is located in sectors at the end of the
flash and it's offset + CONFIG_SYS_VIDEO_LOGO_MAX_SIZE > 0xFFFFFFFF,
the uncompressing time is very long, since processing the
stream is done bytewise (and not blockwise) due to overflow
in inflate_fast() while calculation and checking for enough
input available.

Fix available bitmap data input size for gunzip() to match
the actually available data size to prevent the observed
misbehaviour.

Reported-by: Werner Pfister <werner.pfister at intercontrol.de>
Signed-off-by: Anatolij Gustschin <agust at denx.de>
---
 common/cmd_bmp.c            |    9 +++++++++
 drivers/video/cfb_console.c |   10 ++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index 23fc82f..0640a95 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -32,6 +32,8 @@
 #include <asm/byteorder.h>
 #include <malloc.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static int bmp_info (ulong addr);
 static int bmp_display (ulong addr, int x, int y);
 
@@ -47,6 +49,7 @@ static int bmp_display (ulong addr, int x, int y);
 #ifdef CONFIG_VIDEO_BMP_GZIP
 bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp)
 {
+	unsigned long flash_end;
 	void *dst;
 	unsigned long len;
 	bmp_image_t *bmp;
@@ -55,6 +58,12 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp)
 	 * Decompress bmp image
 	 */
 	len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
+	flash_end = gd->bd->bi_flashstart + gd->bd->bi_flashsize - 1;
+	if (addr >= gd->bd->bi_flashstart && addr <= flash_end) {
+		if (flash_end - addr < CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)
+			len = flash_end - addr + 1;
+	}
+
 	dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
 	if (dst == NULL) {
 		puts("Error: malloc in gunzip failed!\n");
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index b427c84..42b4b21 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -334,6 +334,7 @@ void	console_cursor (int state);
 #define PRINTD(x)
 #endif
 
+DECLARE_GLOBAL_DATA_PTR;
 
 #ifdef CONFIG_CONSOLE_EXTRA_INFO
 extern void video_get_info_str (    /* setup a board string: type, speed, etc. */
@@ -1043,7 +1044,16 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
 		/*
 		 * Could be a gzipped bmp image, try to decrompress...
 		 */
+		unsigned long addr = (unsigned long)bmp;
+		unsigned long flash_end;
+
 		len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
+		flash_end = gd->bd->bi_flashstart + gd->bd->bi_flashsize - 1;
+		if (addr >= gd->bd->bi_flashstart && addr <= flash_end) {
+			if (flash_end - addr < CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)
+				len = flash_end - addr + 1;
+		}
+
 		dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
 		if (dst == NULL) {
 			printf("Error: malloc in gunzip failed!\n");
-- 
1.7.1



More information about the U-Boot mailing list