File xineliboutput-git-bufferoverflow.diff of Package vdr-plugin-xineliboutput

diff --git a/tools/rle.c b/tools/rle.c
index 2c944c7..f108dd2 100644
--- a/tools/rle.c
+++ b/tools/rle.c
@@ -19,6 +19,7 @@
 #include "osd_command.h"
 
 #include "rle.h"
+#include "../logdefs.h"
 
 
 #undef  MAX
@@ -271,9 +272,14 @@ size_t rle_compress_argbrle(uint8_t **rle_data, const uint32_t *data,
   for (y = 0; y < h; y++) {
 
     /* grow buffer ? */
-    if ((ssize_t)(rle_size - ((const uint8_t *)rle - *rle_data)) < w * 4 * 4) {
-      size_t used = (const uint8_t *)rle - *rle_data;
-      rle_size = rle_size < 1 ? w*h/16 : rle_size*2;
+    size_t used = rle - *rle_data;
+    /* RLE worst case is 4 bytes => 6 bytes, factor 1.5 */
+    if ((ssize_t)(rle_size - ((const uint8_t *)rle - *rle_data)) < w * 6) {
+      /* start with about two to three lines buffer, then try to guess a
+       * good size based on the previously used space. Add one line to
+       * make sure rle_size always grows here */
+      rle_size = rle_size < 1 ? w*6*2 : rle_size * h / y + w*6;
+      // LOGMSG("rle_size: %zu used: %zu w: %u h: %u y: %d\n", rle_size, used, w, h, y);
       *rle_data = realloc(*rle_data, rle_size);
       rle = *rle_data + used;
     }
@@ -287,24 +293,40 @@ size_t rle_compress_argbrle(uint8_t **rle_data, const uint32_t *data,
       if (data[x] == color) {
         len++;
       } else {
+        int need = (len < 64) ? 6 : 7;
+        if (used + need > rle_size) {
+          LOGERR("%s:%d not enough space\n", __func__, __LINE__);
+          goto out;
+        }
         rle = write_rle_argb(rle, color, len);
         (*num_rle)++;
         color = data[x];
         len   = 1;
+        used = rle - *rle_data;
       }
     }
 
     if (len) {
+      int need = (len < 64) ? 6 : 7;
+      if (used + need > rle_size) {
+        LOGERR("%s:%d not enough space\n", __func__, __LINE__);
+        break;
+      }
       rle = write_rle_argb(rle, color, len);
       (*num_rle)++;
+      used = rle - *rle_data;
     }
 
     /* end of line marker */
+    if (used + 6 > rle_size) {
+      LOGERR("%s:%d not enough space\n", __func__, __LINE__);
+      break;
+    }
     rle = write_rle_argb(rle, 0, 0);
     (*num_rle)++;
     data += w;
   }
-
+ out:
   return (rle - *rle_data);
 }
 
diff --git a/xine_input_vdr.c b/xine_input_vdr.c
index 3ebc6e6..9a04fe7 100644
--- a/xine_input_vdr.c
+++ b/xine_input_vdr.c
@@ -138,6 +138,7 @@ typedef struct {
 #  include <linux/unistd.h> /* syscall(__NR_gettid) */
 #endif
 
+int SysLogLevel = 1;
 static const char log_module_input_vdr[] = "[input_vdr] ";
 #define LOG_MODULENAME log_module_input_vdr
 #define SysLogLevel    iSysLogLevel
openSUSE Build Service is sponsored by