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

login
register
mail settings
Submitter Anatolij Gustschin
Date July 19, 2011, 12:12 p.m.
Message ID <1311077563-30531-1-git-send-email-agust@denx.de>
Download mbox | patch
Permalink /patch/105467/
State Superseded
Headers show

Comments

Anatolij Gustschin - July 19, 2011, 12:12 p.m.
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@intercontrol.de>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
 common/cmd_bmp.c            |    9 +++++++++
 drivers/video/cfb_console.c |   10 ++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)
Mike Frysinger - July 20, 2011, 3:36 a.m.
On Tuesday, July 19, 2011 08:12:43 Anatolij Gustschin wrote:
> 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.

this doesnt sound right.  the flash region should have no relevance at all to 
the bmp funcs (and the current ones dont check it at all).  also, i'm not sure 
your code currently handles multiple flashes as bi_flashstart really is only 
good for flash_info[0].

if there's an overflow happening, then the overflow should be detected 
generically and handled without any knowledge at all of flashes.
-mike

Patch

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");