This is still quite a dangerous practice, and this commit is more a band-aid
than a definitive fix.
In case a GDALDataset would hold and use a pointer to the GDALDriver that has
created it (which is not common in GDAL drivers though), crash would occur.
Safer but more involved fixes could be:
- to prevent disabling a driver that is in use
- to post-pone the effect of driver disabling to application restart, or when
the last dataset using the driver has been closed
- Fix guess of appropriate nodata value when comparing stat minimum value and
output data type minimum value (copy & paste issue)
- When exporting to GeoPackage, do not promote Byte to a larger type, as this
is unsupported by GeoPackage
- When determining if the output extent is included in the source extent,
use a tolerance to avoid being to sensitive to rounding issues.
- QgsRasterBlock::setIsNoData() and setIsNoDataExcept(): initialize mData to
zero when there is no nodata value, to avoid uninitialized/old memory to
be used when reading bits().
- Lack of error checking on destination provider creation (in saveAsImage mode)
- Wrong computation of number of blocks if dimension is exactly a multiple of
the block size
- Lack of error checking when writing blocks
- Slow computation of non-premultiplied r,g,b values, and inappropriate use
of memcpy()
This should apply to both PROJ < 6 and >=6 builds.
Fixes the following error reported by Valgrind
```
==5848== Invalid read of size 4
==5848== at 0xE5E4195: internal_pj_ctx_get_errno (in /home/even/proj/install-proj-master/lib/libproj.so.15.2.0)
==5848== by 0xE5E16AE: internal_pj_free (in /home/even/proj/install-proj-master/lib/libproj.so.15.2.0)
==5848== by 0xE5F4E78: internal_proj_destroy (in /home/even/proj/install-proj-master/lib/libproj.so.15.2.0)
==5848== by 0x7F961A7: QgsProjUtils::ProjPJDeleter::operator()(PJconsts*) (qgsprojutils.cpp:76)
==5848== by 0x7D2D44C: std::unique_ptr<PJconsts, QgsProjUtils::ProjPJDeleter>::~unique_ptr() (unique_ptr.h:239)
==5848== by 0x7D2C9BD: QgsCoordinateReferenceSystemPrivate::~QgsCoordinateReferenceSystemPrivate() (qgscoordinatereferencesystem_p.h:94)
==5848== by 0x7D2D6FA: QExplicitlySharedDataPointer<QgsCoordinateReferenceSystemPrivate>::~QExplicitlySharedDataPointer() (qshareddata.h:165)
==5848== by 0x7CDFA77: QgsCoordinateReferenceSystem::~QgsCoordinateReferenceSystem() (qgscoordinatereferencesystem.cpp:233)
==5848== by 0x55CC0AF: QgsEllipsoidUtils::EllipsoidParameters::~EllipsoidParameters() (qgsellipsoidutils.h:39)
==5848== by 0x7D8C40B: QHashNode<QString, QgsEllipsoidUtils::EllipsoidParameters>::~QHashNode() (qhash.h:149)
==5848== by 0x7D8C43F: QHash<QString, QgsEllipsoidUtils::EllipsoidParameters>::deleteNode2(QHashData::Node*) (qhash.h:536)
==5848== by 0x9BE3B78: QHashData::free_helper(void (*)(QHashData::Node*)) (in /opt/qt59/lib/libQt5Core.so.5.9.1)
==5848== by 0x7D8C466: QHash<QString, QgsEllipsoidUtils::EllipsoidParameters>::freeData(QHashData*) (qhash.h:576)
==5848== by 0x7D8CCED: QHash<QString, QgsEllipsoidUtils::EllipsoidParameters>::~QHash() (qhash.h:254)
==5848== by 0xA60E369: __cxa_finalize (cxa_finalize.c:56)
==5848== by 0x77BE742: ??? (in /home/even/qgis/QGIS/build/output/lib/libqgis_core.so.3.9.0)
==5848== by 0x4010DF6: _dl_fini (dl-fini.c:235)
==5848== by 0xA60DFF7: __run_exit_handlers (exit.c:82)
==5848== by 0xA60E044: exit (exit.c:104)
==5848== by 0xA5F4836: (below main) (libc-start.c:325)
==5848== Address 0x45db80e0 is 0 bytes inside a block of size 136 free'd
==5848== at 0x4C2F440: operator delete(void*) (vg_replace_malloc.c:586)
==5848== by 0xE5F5A3A: internal_proj_context_destroy (in /home/even/proj/install-proj-master/lib/libproj.so.15.2.0)
==5848== by 0x7F9617A: QgsProjContext::~QgsProjContext() (qgsprojutils.cpp:48)
==5848== by 0xA60E5FE: __call_tls_dtors (cxa_thread_atexit_impl.c:155)
==5848== by 0xA60DF26: __run_exit_handlers (exit.c:40)
==5848== by 0xA60E044: exit (exit.c:104)
==5848== by 0xA5F4836: (below main) (libc-start.c:325)
==5848== Block was alloc'd at
==5848== at 0x4C2E709: operator new(unsigned long, std::nothrow_t const&) (vg_replace_malloc.c:387)
==5848== by 0xE5E445E: internal_pj_ctx_alloc (in /home/even/proj/install-proj-master/lib/libproj.so.15.2.0)
==5848== by 0x7F96151: QgsProjContext::QgsProjContext() (qgsprojutils.cpp:39)
==5848== by 0x7F970A9: __tls_init (qgsprojutils.cpp:31)
==5848== by 0x7F970F3: TLS wrapper function for QgsProjContext::sProjContext (in /home/even/qgis/QGIS/build/output/lib/libqgis_core.so.3.9.0)
==5848== by 0x7F96186: QgsProjContext::get() (qgsprojutils.cpp:57)
==5848== by 0x7D86B13: QgsEllipsoidUtils::definitions() (qgsellipsoidutils.cpp:351)
==5848== by 0x7D863FE: QgsEllipsoidUtils::ellipsoidParameters(QString const&)::{lambda()#1}::operator()() const (qgsellipsoidutils.cpp:173)
==5848== by 0x7D87EE1: void std::_Bind_simple<QgsEllipsoidUtils::ellipsoidParameters(QString const&)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) (functional:1531)
==5848== by 0x7D87BC5: std::_Bind_simple<QgsEllipsoidUtils::ellipsoidParameters(QString const&)::{lambda()#1} ()>::operator()() (functional:1520)
==5848== by 0x7D879A2: void std::__once_call_impl<std::_Bind_simple<QgsEllipsoidUtils::ellipsoidParameters(QString const&)::{lambda()#1} ()> >() (mutex:706)
==5848== by 0x10A6AA98: __pthread_once_slow (pthread_once.c:116)
==5848== by 0x7D863CE: __gthread_once(int*, void (*)()) (gthr-default.h:699)
==5848== by 0x7D8787F: void std::call_once<QgsEllipsoidUtils::ellipsoidParameters(QString const&)::{lambda()#1}>(std::once_flag&, QgsEllipsoidUtils::ellipsoidParameters(QString const&)::{lambda()#1}&&) (mutex:738)
==5848== by 0x7D86476: QgsEllipsoidUtils::ellipsoidParameters(QString const&) (qgsellipsoidutils.cpp:174)
==5848== by 0x7E8D572: QgsMapSettings::setEllipsoid(QString const&) (qgsmapsettings.cpp:322)
==5848== by 0x6A4E5F1: QgsMapCanvas::QgsMapCanvas(QWidget*) (qgsmapcanvas.cpp:143)
==5848== by 0x5110841: QgisApp::QgisApp(QSplashScreen*, bool, bool, QString const&, QString const&, QWidget*, QFlags<Qt::WindowType>) (qgisapp.cpp:803)
==5848== by 0x417DB9: main (main.cpp:1339)
==5848==
```