Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix STAC memory leaks #60466

Merged
merged 7 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions src/core/stac/qgsstaccontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
QgsStacController::~QgsStacController()
{
qDeleteAll( mReplies );
qDeleteAll( mFetchedStacObjects );
qDeleteAll( mFetchedItemCollections );
qDeleteAll( mFetchedCollections );
}


int QgsStacController::fetchStacObjectAsync( const QUrl &url )
{
QNetworkReply *reply = fetchAsync( url );
Expand Down Expand Up @@ -382,8 +384,3 @@ QgsStacItem *QgsStacController::openLocalItem( const QString &fileName ) const
parser.setBaseUrl( fileName );
return parser.item();
}





9 changes: 5 additions & 4 deletions src/core/stac/qgsstacdataitems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ void QgsStacItemItem::itemRequestFinished( int requestId, QString error )
}
else
{
delete object;
mIconName = QStringLiteral( "/mIconDelete.svg" );
mName = error;
}
Expand Down Expand Up @@ -297,7 +298,7 @@ void QgsStacCatalogItem::childrenCreated()

void QgsStacCatalogItem::onControllerFinished( int requestId, const QString &error )
{
for ( auto child : std::as_const( mChildren ) )
for ( QgsDataItem *child : std::as_const( mChildren ) )
{
if ( child->state() != Qgis::BrowserItemState::NotPopulated )
continue;
Expand Down Expand Up @@ -335,7 +336,7 @@ QVector<QgsDataItem *> QgsStacCatalogItem::createChildren()
bool hasCollectionsEndpoint = false;
if ( supportsApi )
{
for ( const auto &link : links )
for ( const QgsStacLink &link : links )
{
if ( link.relation() == QLatin1String( "items" ) )
{
Expand All @@ -351,7 +352,7 @@ QVector<QgsDataItem *> QgsStacCatalogItem::createChildren()
}
}

for ( const auto &link : links )
for ( const QgsStacLink &link : links )
{
// skip hierarchical navigation links
if ( link.relation() == QLatin1String( "self" ) ||
Expand Down Expand Up @@ -586,7 +587,7 @@ QgsStacRootItem::QgsStacRootItem( QgsDataItem *parent, const QString &name, cons
QVector<QgsDataItem *> QgsStacRootItem::createChildren()
{
QVector<QgsDataItem *> connections;
const auto connectionList = QgsStacConnection::connectionList();
const QStringList connectionList = QgsStacConnection::connectionList();
for ( const QString &connName : connectionList )
{
QgsDataItem *conn = new QgsStacConnectionItem( this, connName );
Expand Down
55 changes: 37 additions & 18 deletions src/core/stac/qgsstacparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,54 +480,73 @@ QString QgsStacParser::getString( const nlohmann::json &data )

QgsStacItemCollection *QgsStacParser::itemCollection()
{
std::vector< std::unique_ptr<QgsStacItem> > items;
QVector< QgsStacLink > links;
int numberMatched = -1;
try
{
QVector< QgsStacLink > links = parseLinks( mData.at( "links" ) );
links = parseLinks( mData.at( "links" ) );

QVector< QgsStacItem * > items;
items.reserve( static_cast<int>( mData.at( "features" ).size() ) );
items.reserve( mData.at( "features" ).size() );
for ( auto &item : mData.at( "features" ) )
{
QgsStacItem *i = parseItem( item );
if ( i )
items.append( i );
items.emplace_back( parseItem( item ) );
}

const int numberMatched = mData.contains( "numberMatched" ) ? mData["numberMatched"].get<int>() : -1;

return new QgsStacItemCollection( items, links, numberMatched );
if ( mData.contains( "numberMatched" ) )
numberMatched = mData["numberMatched"].get<int>();
}
catch ( nlohmann::json::exception &ex )
{
mError = QStringLiteral( "Error parsing ItemCollection" );
QgsDebugError( QStringLiteral( "Error parsing ItemCollection: %1" ).arg( ex.what() ) );
return nullptr;
}

QVector< QgsStacItem *> rawItems;
rawItems.reserve( static_cast<int>( items.size() ) );
for ( std::unique_ptr<QgsStacItem> &i : items )
{
if ( i )
rawItems.append( i.release() );
}

return new QgsStacItemCollection( rawItems, links, numberMatched );
}

QgsStacCollections *QgsStacParser::collections()
{
std::vector< std::unique_ptr<QgsStacCollection> > cols;
QVector< QgsStacLink > links;
int numberMatched = -1;

try
{
QVector< QgsStacLink > links = parseLinks( mData.at( "links" ) );
links = parseLinks( mData.at( "links" ) );

QVector< QgsStacCollection * > cols;
cols.reserve( static_cast<int>( mData.at( "collections" ).size() ) );
cols.reserve( mData.at( "collections" ).size() );
for ( auto &col : mData.at( "collections" ) )
{
QgsStacCollection *c = parseCollection( col );
if ( c )
cols.append( c );
cols.emplace_back( parseCollection( col ) );
}

const int numberMatched = mData.contains( "numberMatched" ) ? mData["numberMatched"].get<int>() : -1;

return new QgsStacCollections( cols, links, numberMatched );
if ( mData.contains( "numberMatched" ) )
numberMatched = mData["numberMatched"].get<int>();
}
catch ( nlohmann::json::exception &ex )
{
mError = QStringLiteral( "Error parsing ItemCollection" );
QgsDebugError( QStringLiteral( "Error parsing ItemCollection: %1" ).arg( ex.what() ) );
return nullptr;
}

QVector< QgsStacCollection * > rawCols;
rawCols.reserve( static_cast<int>( cols.size() ) );
for ( std::unique_ptr<QgsStacCollection> &c : cols )
{
if ( c )
rawCols.append( c.release() );
}

return new QgsStacCollections( rawCols, links, numberMatched );
}
8 changes: 4 additions & 4 deletions src/gui/stac/qgsstacsourceselect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ void QgsStacSourceSelect::cmbConnections_currentTextChanged( const QString &text
void QgsStacSourceSelect::onStacObjectRequestFinished( int requestId, QString error )
{
QgsDebugMsgLevel( QStringLiteral( "Finished object request %1" ).arg( requestId ), 2 );
QgsStacObject *obj = mStac->takeStacObject( requestId );
QgsStacCatalog *cat = dynamic_cast<QgsStacCatalog *>( obj );
std::unique_ptr<QgsStacObject> obj( mStac->takeStacObject( requestId ) );
QgsStacCatalog *cat = dynamic_cast<QgsStacCatalog *>( obj.get() );

if ( !cat )
{
Expand Down Expand Up @@ -311,7 +311,7 @@ void QgsStacSourceSelect::onStacObjectRequestFinished( int requestId, QString er
void QgsStacSourceSelect::onCollectionsRequestFinished( int requestId, QString error )
{
QgsDebugMsgLevel( QStringLiteral( "Finished collections request %1" ).arg( requestId ), 2 );
QgsStacCollections *cols = mStac->takeCollections( requestId );
std::unique_ptr<QgsStacCollections> cols( mStac->takeCollections( requestId ) );

if ( !cols )
{
Expand All @@ -333,7 +333,7 @@ void QgsStacSourceSelect::onCollectionsRequestFinished( int requestId, QString e
void QgsStacSourceSelect::onItemCollectionRequestFinished( int requestId, QString error )
{
QgsDebugMsgLevel( QStringLiteral( "Finished item collection request %1" ).arg( requestId ), 2 );
QgsStacItemCollection *col = mStac->takeItemCollection( requestId );
std::unique_ptr<QgsStacItemCollection> col( mStac->takeItemCollection( requestId ) );

if ( !col )
{
Expand Down
Loading