[Marble-commits] branches/KDE/4.5/kdeedu/marble/src/lib/geodata/data

Jens-Michael Hoffmann jensmh at gmx.de
Tue Nov 9 22:16:00 CET 2010


SVN commit 1194778 by jmhoffmann:

GeoDataPlacemark: Fix potential crash.

In the assignment operator of GeoDataPlacemarkPrivate m_geometry is deleted
without setting the pointer to 0 afterwards. In case the "other"
GeoDataPlacemarkPrivate does not have a geometry this might lead to a
double delete.

Besides that, the return statement might cause problems in case code
is added at the end of the method without carefully looking.

In addtition the geometry assignment is now (well, kind of) exception-safe.
Even if exceptions are not used it seems nicer to use an existing wide spread
idiom ("first do the real work w/o modifying state, then assign").

This is a backport of svn commit 1194384.

 M  +11 -9     GeoDataPlacemark_p.h  


--- branches/KDE/4.5/kdeedu/marble/src/lib/geodata/data/GeoDataPlacemark_p.h #1194777:1194778
@@ -41,32 +41,34 @@
         m_area = other.m_area;
         m_population = other.m_population;
 
-        delete m_geometry;
-        if( !other.m_geometry ) return;
-
+        GeoDataGeometry * geometry = 0;
+        if ( other.m_geometry ) {
         switch( other.m_geometry->geometryId() ) {
             case InvalidGeometryId:
                 break;
             case GeoDataPointId:
-                m_geometry = new GeoDataPoint( *static_cast<GeoDataPoint*>( other.m_geometry ) );
+                geometry = new GeoDataPoint( *static_cast<GeoDataPoint*>( other.m_geometry ) );
                 break;
             case GeoDataLineStringId:
-                m_geometry = new GeoDataLineString( *static_cast<GeoDataLineString*>( other.m_geometry ) );
+                geometry = new GeoDataLineString( *static_cast<GeoDataLineString*>( other.m_geometry ) );
                 break;
             case GeoDataLinearRingId:
-                m_geometry = new GeoDataLinearRing( *static_cast<GeoDataLinearRing*>( other.m_geometry ) );
+                geometry = new GeoDataLinearRing( *static_cast<GeoDataLinearRing*>( other.m_geometry ) );
                 break;
             case GeoDataPolygonId:
-                m_geometry = new GeoDataPolygon( *static_cast<GeoDataPolygon*>( other.m_geometry ) );
+                geometry = new GeoDataPolygon( *static_cast<GeoDataPolygon*>( other.m_geometry ) );
                 break;
             case GeoDataMultiGeometryId:
-                m_geometry = new GeoDataMultiGeometry( *static_cast<GeoDataMultiGeometry*>( other.m_geometry ) );
+                geometry = new GeoDataMultiGeometry( *static_cast<GeoDataMultiGeometry*>( other.m_geometry ) );
                 break;
             case GeoDataModelId:
                 break;
             default: break;
-        };
     }
+        }
+        delete m_geometry;
+        m_geometry = geometry;
+    }
 
     virtual void* copy() 
     { 


More information about the Marble-commits mailing list