Skip to content

Commit

Permalink
Fix use-after-free
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 11, 2024
1 parent 907aeb6 commit 7525fcc
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 7 deletions.
9 changes: 9 additions & 0 deletions python/PyQt6/core/auto_generated/qgsproxyfeaturesink.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,25 @@ proxy sink can be safely deleted without affecting the destination sink.
Constructs a new QgsProxyFeatureSink which forwards features onto a destination ``sink``.
%End
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() );

virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() );

virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() );

virtual QString lastError() const;

virtual bool flushBuffer();

virtual void finalize();


QgsFeatureSink *destinationSink();
%Docstring
Returns the destination :py:class:`QgsFeatureSink` which the proxy will forward features to.
%End

protected:

};


Expand Down
9 changes: 9 additions & 0 deletions python/core/auto_generated/qgsproxyfeaturesink.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,25 @@ proxy sink can be safely deleted without affecting the destination sink.
Constructs a new QgsProxyFeatureSink which forwards features onto a destination ``sink``.
%End
virtual bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() );

virtual bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() );

virtual bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() );

virtual QString lastError() const;

virtual bool flushBuffer();

virtual void finalize();


QgsFeatureSink *destinationSink();
%Docstring
Returns the destination :py:class:`QgsFeatureSink` which the proxy will forward features to.
%End

protected:

};


Expand Down
5 changes: 4 additions & 1 deletion src/core/processing/qgsprocessingutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2008,7 +2008,10 @@ QgsProcessingFeatureSink::~QgsProcessingFeatureSink()
}

if ( mOwnsSink )
delete destinationSink();
{
delete mSink;
mSink = nullptr;
}
}

void QgsProcessingFeatureSink::finalize()
Expand Down
45 changes: 45 additions & 0 deletions src/core/qgsproxyfeaturesink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,48 @@
QgsProxyFeatureSink::QgsProxyFeatureSink( QgsFeatureSink *sink )
: mSink( sink )
{}

bool QgsProxyFeatureSink::addFeature( QgsFeature &feature, Flags flags )
{
if ( !mSink )
return false;

return mSink->addFeature( feature, flags );
}

bool QgsProxyFeatureSink::addFeatures( QgsFeatureList &features, Flags flags )
{
if ( !mSink )
return false;

return mSink->addFeatures( features, flags );
}

bool QgsProxyFeatureSink::addFeatures( QgsFeatureIterator &iterator, Flags flags )
{
if ( !mSink )
return false;

return mSink->addFeatures( iterator, flags );
}

QString QgsProxyFeatureSink::lastError() const
{
return mSink ? mSink->lastError() : QString();
}

bool QgsProxyFeatureSink::flushBuffer()
{
if ( !mSink )
return false;

return mSink->flushBuffer();
}

void QgsProxyFeatureSink::finalize()
{
if ( mSink )
{
mSink->finalize();
}
}
14 changes: 8 additions & 6 deletions src/core/qgsproxyfeaturesink.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,21 @@ class CORE_EXPORT QgsProxyFeatureSink : public QgsFeatureSink
* Constructs a new QgsProxyFeatureSink which forwards features onto a destination \a sink.
*/
QgsProxyFeatureSink( QgsFeatureSink *sink );
bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override { return mSink->addFeature( feature, flags ); }
bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override { return mSink->addFeatures( features, flags ); }
bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override { return mSink->addFeatures( iterator, flags ); }
QString lastError() const override { return mSink->lastError(); }
bool flushBuffer() override { return mSink->flushBuffer(); }
bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override;
bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override;
bool addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override;
QString lastError() const override;
bool flushBuffer() override;
void finalize() override;

/**
* Returns the destination QgsFeatureSink which the proxy will forward features to.
*/
QgsFeatureSink *destinationSink() { return mSink; }

private:
protected:

//! Underlying destination sink
QgsFeatureSink *mSink = nullptr;
};

Expand Down
2 changes: 2 additions & 0 deletions tests/src/analysis/testqgsprocessing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,7 @@ void TestQgsProcessing::createFeatureSink()
QCOMPARE( layer->featureCount(), 0L );
QVERIFY( sink->addFeature( f ) );
QCOMPARE( layer->featureCount(), 1L );
sink.reset();
context.temporaryLayerStore()->removeAllMapLayers();
layer = nullptr;

Expand Down Expand Up @@ -2392,6 +2393,7 @@ void TestQgsProcessing::createFeatureSink()
QCOMPARE( layer->featureCount(), 0L );
QVERIFY( sink->addFeature( f ) );
QCOMPARE( layer->featureCount(), 1L );
sink.reset();
context.temporaryLayerStore()->removeAllMapLayers();

// non memory layer output
Expand Down

0 comments on commit 7525fcc

Please sign in to comment.