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