[fdo-trac] #331: Serious bug in FdoPtr<T> copy ctor (patch attached)

FDO trac_fdo at osgeo.org
Wed Apr 23 03:57:53 EDT 2008


#331: Serious bug in FdoPtr<T> copy ctor (patch attached)
-----------------------+----------------------------------------------------
   Reporter:  Kosta    |       Owner:  gregboone
       Type:  defect   |      Status:  new      
   Priority:  blocker  |   Milestone:  3.4.0    
  Component:  FDO API  |     Version:  3.3.1    
   Severity:  1        |    Keywords:           
External_id:           |  
-----------------------+----------------------------------------------------
 If you assign an !FdoPtr<T> object "t" to a new !FdoPtr<U> object "u"
 where U is a base class of T the ref count is not increased. Example:

 {{{
 FdoPtr<FdoIPolygon> poly = FdoFgfGeometryFactory::GetInstance()
     ->CreatePolygon(outerRing, innerRings);
 // ref count of poly == 1

 FdoPtr<FdoIGeometry> geom = poly;
 // ref count of poly (and geom) still == 1
 }}}

 If both pointers go out of scope the pointed to object gets deleted by the
 first !FdoPtr-dtor and the second pointer holds a dangling pointer
 resulting in a crash during destruction...

 The problem is that !FdoPtr<T> only defines a copy ctor for type T. So
 during construction of the "geom" pointer, first
 "!FdoPtr<FdoIPolygon>::operator FdoIPolygon*()" is called on the "poly"
 pointer and the resulting plain "FdoIPolygon*" pointer is feed into
 "!FdoPtr<FdoIGeometry>::!FdoPtr(FdoIGeometry* t)"; but this ctor does not
 increase the reference count of the pointed to object!

 Proposed patch:

 Change the existing impl of the copy ctor from:
 {{{
     /// \brief
     /// FdoPtr copy constructor. Wraps a new FdoPtr around the object
     /// referenced by lp.
     ///
     /// \param lp
     /// Input the FdoPtr to copy from.
     ///
     /// \return
     /// Returns a FdoPtr
     ///
     /// \note
     /// This operator adds a reference on the object.
     FdoPtr(const FdoPtr<T>& lp) throw()
     {
         p = lp.p;
         if (p != NULL)
             p->AddRef();
     }
 }}}
 into:
 {{{
     /// \brief
     /// FdoPtr copy constructor. Wraps a new FdoPtr around the object
     /// referenced by lp. Type U must be convertible to type T.     <<<<<
 here
     ///
     /// \param lp
     /// Input the FdoPtr to copy from.
     ///
     /// \return
     /// Returns a FdoPtr
     ///
     /// \note
     /// This operator adds a reference on the object.
     template <class U>                                              <<<<<
 here
     FdoPtr(const FdoPtr<U>& lp) throw()                             <<<<<
 here
     {
         p = lp.p;
         if (p != NULL)
             p->AddRef();
     }
 }}}

-- 
Ticket URL: <http://trac.osgeo.org/fdo/ticket/331>
FDO <http://fdo.osgeo.org/>
Feature Data Objects


More information about the fdo-trac mailing list