Segfault if cSkinDisplayMessage is replaced by another display object

Message ID 456E3C35.5080708@gmx.de
State New
Headers

Commit Message

Udo Richter Nov. 30, 2006, 2:04 a.m. UTC
  Hi Klaus,


I've isolated an null pointer dereferencing bug in cSkins::Message():

In the very rare case that a message is displayed using a 
cSkinDisplayMessage object, and the message is not removed before 
another cSkinDisplay object takes control, the next attempt to display a 
message while no cSkinDisplay::Current() object is available causes a 
segfault.

The reason is that the cSkins::displayMessage pointer is not cleared if 
another cSkinDisplay object takes over. cSkins::Message() sees an 
existing displayMessage object, but accesses the non-existing 
cSkinDisplay::Current(), assuming they're both the same.

The only way I know how to trigger this is to use mtStatus messages and 
allow user activity while the message is shown. I don't think that plain 
VDR can trigger this on its own.

The attached patch changes cSkins::Message() by only checking the 
existence of cSkinDisplay::Current(). If no current cSkinDisplay exists, 
any old displayMessage object is deleted and a new one is created.

Cheers,

Udo
  

Patch

--- skins.c.orig	2006-11-30 02:19:41.705523304 +0100
+++ skins.c	2006-11-30 02:33:28.269230960 +0100
@@ -226,8 +226,11 @@ 
     }
   if (!Current())
      return kNone;
-  if (!cSkinDisplay::Current() && !displayMessage)
+  if (!cSkinDisplay::Current()) {
+     if (displayMessage)
+        delete displayMessage;
      displayMessage = Current()->DisplayMessage();
+     }
   cSkinDisplay::Current()->SetMessage(Type, s);
   cSkinDisplay::Current()->Flush();
   cStatus::MsgOsdStatusMessage(s);