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.pfis...@intercontrol.de>
Signed-off-by: Anatolij Gustschin <ag...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to