File libEMF-1.0.7-handle-corrupted-metafiles.patch of Package libEMF.15327

Index: libEMF-1.0.7/libemf/libemf.cpp
===================================================================
--- libEMF-1.0.7.orig/libemf/libemf.cpp
+++ libEMF-1.0.7/libemf/libemf.cpp
@@ -211,10 +211,19 @@ namespace EMF {
    */
   OBJECT* GLOBALOBJECTS::find ( const HGDIOBJ handle )
   {
-    if ( handle & ENHMETA_STOCK_OBJECT )
-      return objects[ handle & (~ENHMETA_STOCK_OBJECT) ];
-    else
+    if ( handle & ENHMETA_STOCK_OBJECT ) {
+      size_t o = handle & (~ENHMETA_STOCK_OBJECT);
+      if ( o >= objects.size() ) {
+        return NULL;
+      }
+      return objects[o];
+    }
+    else {
+      if ( handle >= objects.size() ) {
+        return NULL;
+      }
       return objects[ handle ];
+    }
   }
 
   /*!
@@ -538,7 +547,8 @@ namespace EMF {
     // destination dc wants to see. emf_handles is manipulated when
     // a Create* object record is executed.
 
-    if ( !( ihObject & ENHMETA_STOCK_OBJECT ) )
+    if ( !( ihObject & ENHMETA_STOCK_OBJECT ) and
+         source->emf_handles.find( ihObject ) != source->emf_handles.end() )
       DeleteObject( source->emf_handles[ihObject] );
   }
 
@@ -1021,8 +1031,11 @@ extern "C" {
 
     delete[] filename_a;
 
-    if ( fp == 0 )
+    if ( fp == 0 ) {
+      std::cerr << "GetEnhMetaFileW read error. cannot continue"
+                << std::endl;
       return 0;
+    }
 
     // Create an implicit device context for this metafile. This
     // also creates an implicit metafile header.
@@ -1037,6 +1050,8 @@ extern "C" {
     dc->ds >> emr;
 
     if ( emr.iType != EMR_HEADER ) {
+      std::cerr << "GetEnhMetaFileW read error. cannot continue: Not an EMF"
+                << std::endl;
       DeleteDC( dc->handle );
       return 0;
     }
Index: libEMF-1.0.7/libemf/libemf.h
===================================================================
--- libEMF-1.0.7.orig/libemf/libemf.h
+++ libEMF-1.0.7/libemf/libemf.h
@@ -26,6 +26,7 @@
 #include <map>
 #include <functional>
 #include <algorithm>
+#include <stdexcept>
 
 #include <config.h>
 #include <libEMF/emf.h>
@@ -3538,6 +3539,21 @@ namespace EMF {
 
       ds >> counts;
 
+      // Counts have to add up to less than the number of points
+      // we have. DWORD is unsigned so we most care about overflow.
+      DWORD n = 0, n_old = 0;
+      for ( DWORD c = 0; c < nPolys; ++c ) {
+        n_old = n;
+        n += lcounts[c];
+        if ( n < n_old ) {
+          throw std::runtime_error( "Unsigned overflow" );
+        }
+      }
+      if ( n > cptl ) {
+        throw std::runtime_error( "Too few points" );
+      }
+
+
       lpoints = new POINTL[cptl];
 
       POINTLARRAY points( lpoints, cptl );
@@ -3728,6 +3744,20 @@ namespace EMF {
 
       ds >> counts;
 
+      // Counts have to add up to less than the number of points
+      // we have. DWORD is unsigned so we most care about overflow.
+      DWORD n = 0, n_old = 0;
+      for ( DWORD c = 0; c < nPolys; ++c ) {
+        n_old = n;
+        n += lcounts[c];
+        if ( n < n_old ) {
+          throw std::runtime_error( "Unsigned overflow" );
+        }
+      }
+      if ( n > cpts ) {
+        throw std::runtime_error( "Too few points" );
+      }
+
       lpoints = new POINT16[cpts];
 
       POINT16ARRAY points( lpoints, cpts );
openSUSE Build Service is sponsored by