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

Limit number of C++ exceptions thrown & caught internally #4183

Merged
merged 3 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions include/proj/coordinateoperation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1704,8 +1704,8 @@ class PROJ_GCC_DLL Transformation : public SingleOperation {
PROJ_INTERNAL const std::string &
getPROJ4NadgridsCompatibleFilename() const;

PROJ_FOR_TEST std::vector<double>
getTOWGS84Parameters() const; // throw(io::FormattingException)
PROJ_FOR_TEST std::vector<double> getTOWGS84Parameters(
bool canThrowException) const; // throw(io::FormattingException)

PROJ_INTERNAL const std::string &getHeightToGeographic3DFilename() const;

Expand Down
8 changes: 4 additions & 4 deletions include/proj/coordinatesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ class AxisDirection : public util::CodeList {
valueOf(const std::string &nameIn) noexcept;
//! @endcond

AxisDirection(const AxisDirection&) = delete;
AxisDirection& operator=(const AxisDirection&) = delete;
AxisDirection(AxisDirection&&) = delete;
AxisDirection& operator=(AxisDirection&&) = delete;
AxisDirection(const AxisDirection &) = delete;
AxisDirection &operator=(const AxisDirection &) = delete;
AxisDirection(AxisDirection &&) = delete;
AxisDirection &operator=(AxisDirection &&) = delete;

PROJ_DLL static const AxisDirection NORTH;
PROJ_DLL static const AxisDirection NORTH_NORTH_EAST;
Expand Down
2 changes: 1 addition & 1 deletion scripts/reference_exported_symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ osgeo::proj::operation::Transformation::createTimeDependentPositionVector(osgeo:
osgeo::proj::operation::Transformation::createTOWGS84(dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, std::vector<double, std::allocator<double> > const&)
osgeo::proj::operation::Transformation::createVERTCON(osgeo::proj::util::PropertyMap const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, std::string const&, std::vector<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> >, std::allocator<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> > > > const&)
osgeo::proj::operation::Transformation::createVerticalOffset(osgeo::proj::util::PropertyMap const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::crs::CRS> > const&, osgeo::proj::common::Length const&, std::vector<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> >, std::allocator<dropbox::oxygen::nn<std::shared_ptr<osgeo::proj::metadata::PositionalAccuracy> > > > const&)
osgeo::proj::operation::Transformation::getTOWGS84Parameters() const
osgeo::proj::operation::Transformation::getTOWGS84Parameters(bool) const
osgeo::proj::operation::Transformation::inverse() const
osgeo::proj::operation::Transformation::sourceCRS() const
osgeo::proj::operation::Transformation::targetCRS() const
Expand Down
87 changes: 51 additions & 36 deletions src/iso19111/c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,41 +194,53 @@ getDBcontextNoException(PJ_CONTEXT *ctx, const char *function) {
PJ *pj_obj_create(PJ_CONTEXT *ctx, const BaseObjectNNPtr &objIn) {
auto coordop = dynamic_cast<const CoordinateOperation *>(objIn.get());
if (coordop) {
auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
auto formatter = PROJStringFormatter::create(
PROJStringFormatter::Convention::PROJ_5, std::move(dbContext));
auto projString = coordop->exportToPROJString(formatter.get());
if (proj_context_is_network_enabled(ctx)) {
ctx->defer_grid_opening = true;
}
auto pj = pj_create_internal(ctx, projString.c_str());
ctx->defer_grid_opening = false;
if (pj) {
pj->iso_obj = objIn;
pj->iso_obj_is_coordinate_operation = true;
auto sourceEpoch = coordop->sourceCoordinateEpoch();
auto targetEpoch = coordop->targetCoordinateEpoch();
if (sourceEpoch.has_value()) {
if (!targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
sourceEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
}
} else {
if (targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
targetEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
auto singleOp = dynamic_cast<const SingleOperation *>(coordop);
bool bTryToExportToProj = true;
if (singleOp && singleOp->method()->nameStr() == "unnamed") {
// Can happen for example when the GDAL GeoTIFF SRS builder
// creates a dummy conversion when building the SRS, before setting
// the final map projection. This avoids exportToPROJString() from
// throwing an exception.
bTryToExportToProj = false;
}
if (bTryToExportToProj) {
auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
auto formatter = PROJStringFormatter::create(
PROJStringFormatter::Convention::PROJ_5,
std::move(dbContext));
auto projString = coordop->exportToPROJString(formatter.get());
if (proj_context_is_network_enabled(ctx)) {
ctx->defer_grid_opening = true;
}
auto pj = pj_create_internal(ctx, projString.c_str());
ctx->defer_grid_opening = false;
if (pj) {
pj->iso_obj = objIn;
pj->iso_obj_is_coordinate_operation = true;
auto sourceEpoch = coordop->sourceCoordinateEpoch();
auto targetEpoch = coordop->targetCoordinateEpoch();
if (sourceEpoch.has_value()) {
if (!targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
sourceEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
}
} else {
if (targetEpoch.has_value()) {
pj->hasCoordinateEpoch = true;
pj->coordinateEpoch =
targetEpoch->coordinateEpoch().convertToUnit(
common::UnitOfMeasure::YEAR);
}
}
return pj;
}
return pj;
} catch (const std::exception &) {
// Silence, since we may not always be able to export as a
// PROJ string.
}
} catch (const std::exception &) {
// Silence, since we may not always be able to export as a
// PROJ string.
}
}
auto pj = pj_new();
Expand Down Expand Up @@ -7749,16 +7761,19 @@ int proj_coordoperation_get_towgs84_values(PJ_CONTEXT *ctx,
}
return FALSE;
}
try {
auto values = transf->getTOWGS84Parameters();

const auto values = transf->getTOWGS84Parameters(false);
if (!values.empty()) {
for (int i = 0;
i < value_count && static_cast<size_t>(i) < values.size(); i++) {
out_values[i] = values[i];
}
return TRUE;
} catch (const std::exception &e) {
} else {
if (emit_error_if_incompatible) {
proj_log_error(ctx, __FUNCTION__, e.what());
proj_log_error(ctx, __FUNCTION__,
"Transformation cannot be formatted as WKT1 TOWGS84 "
"parameters");
}
return FALSE;
}
Expand Down
21 changes: 9 additions & 12 deletions src/iso19111/crs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,11 +696,10 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(

const auto takeIntoAccountCandidate =
[&](const operation::TransformationNNPtr &transf) {
try {
transf->getTOWGS84Parameters();
} catch (const std::exception &) {
if (transf->getTOWGS84Parameters(false).empty()) {
return;
}

candidateCount++;
if (candidateBoundCRS == nullptr) {
candidateCount = 1;
Expand Down Expand Up @@ -1426,13 +1425,12 @@ CRSNNPtr CRS::promoteTo3D(const std::string &newName,
auto base3DCRS = boundCRS->baseCRS()->promoteTo3D(
newName, dbContext, verticalAxisIfNotAlreadyPresent);
auto transf = boundCRS->transformation();
try {
transf->getTOWGS84Parameters();
if (!transf->getTOWGS84Parameters(false).empty()) {
return BoundCRS::create(
createProperties(), base3DCRS,
boundCRS->hubCRS()->promoteTo3D(std::string(), dbContext),
transf->promoteTo3D(std::string(), dbContext));
} catch (const io::FormattingException &) {
} else {
return BoundCRS::create(base3DCRS, boundCRS->hubCRS(),
std::move(transf));
}
Expand Down Expand Up @@ -1481,13 +1479,12 @@ CRSNNPtr CRS::demoteTo2D(const std::string &newName,
else if (auto boundCRS = dynamic_cast<const BoundCRS *>(this)) {
auto base2DCRS = boundCRS->baseCRS()->demoteTo2D(newName, dbContext);
auto transf = boundCRS->transformation();
try {
transf->getTOWGS84Parameters();
if (!transf->getTOWGS84Parameters(false).empty()) {
return BoundCRS::create(
base2DCRS,
boundCRS->hubCRS()->demoteTo2D(std::string(), dbContext),
transf->demoteTo2D(std::string(), dbContext));
} catch (const io::FormattingException &) {
} else {
return BoundCRS::create(base2DCRS, boundCRS->hubCRS(), transf);
}
}
Expand Down Expand Up @@ -5985,7 +5982,7 @@ void BoundCRS::_exportToWKT(io::WKTFormatter *formatter) const {
io::FormattingException::Throw(
"Cannot export BoundCRS with non-WGS 84 hub CRS in WKT1");
}
auto params = d->transformation()->getTOWGS84Parameters();
auto params = d->transformation()->getTOWGS84Parameters(true);
if (!formatter->useESRIDialect()) {
formatter->setTOWGS84Parameters(params);
}
Expand Down Expand Up @@ -6075,7 +6072,7 @@ void BoundCRS::_exportToPROJString(
formatter->setHDatumExtension(std::string());
} else {
if (isTOWGS84Compatible()) {
auto params = transformation()->getTOWGS84Parameters();
auto params = transformation()->getTOWGS84Parameters(true);
formatter->setTOWGS84Parameters(params);
}
crs_exportable->_exportToPROJString(formatter);
Expand Down Expand Up @@ -6137,7 +6134,7 @@ BoundCRS::_identify(const io::AuthorityFactoryPtr &authorityFactory) const {
}
bool refIsNullTransform = false;
if (isTOWGS84Compatible()) {
auto params = transformation()->getTOWGS84Parameters();
auto params = transformation()->getTOWGS84Parameters(true);
if (params == std::vector<double>{0, 0, 0, 0, 0, 0, 0}) {
refIsNullTransform = true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/iso19111/operation/singleoperation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,8 +1443,8 @@ bool SingleOperation::_isEquivalentTo(const util::IComparable *other,
isTOWGS84Transf(otherMethodEPSGCode)) {
auto transf = static_cast<const Transformation *>(this);
auto otherTransf = static_cast<const Transformation *>(otherSO);
auto params = transf->getTOWGS84Parameters();
auto otherParams = otherTransf->getTOWGS84Parameters();
auto params = transf->getTOWGS84Parameters(true);
auto otherParams = otherTransf->getTOWGS84Parameters(true);
assert(params.size() == 7);
assert(otherParams.size() == 7);
for (size_t i = 0; i < 7; i++) {
Expand Down
10 changes: 8 additions & 2 deletions src/iso19111/operation/transformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,14 @@ Transformation::demoteTo2D(const std::string &,
* can be used as the value of the WKT1 TOWGS84 parameter or
* PROJ +towgs84 parameter.
*
* @param canThrowException if true, an exception is thrown if the method fails,
* otherwise an empty vector is returned in case of failure.
* @return a vector of 7 values if valid, otherwise a io::FormattingException
* is thrown.
* @throws io::FormattingException
*/
std::vector<double>
Transformation::getTOWGS84Parameters() const // throw(io::FormattingException)
std::vector<double> Transformation::getTOWGS84Parameters(
bool canThrowException) const // throw(io::FormattingException)
{
// GDAL WKT1 assumes EPSG:9606 / Position Vector convention

Expand Down Expand Up @@ -297,6 +299,8 @@ Transformation::getTOWGS84Parameters() const // throw(io::FormattingException)
(foundRotX && foundRotY && foundRotZ && foundScale))) {
return params;
} else {
if (!canThrowException)
return {};
throw io::FormattingException(
"Missing required parameter values in transformation");
}
Expand All @@ -321,6 +325,8 @@ Transformation::getTOWGS84Parameters() const // throw(io::FormattingException)
}
#endif

if (!canThrowException)
return {};
throw io::FormattingException(
"Transformation cannot be formatted as WKT1 TOWGS84 parameters");
}
Expand Down
2 changes: 1 addition & 1 deletion src/projections/imoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static double compute_zone_x_boundary(PJ *P, double lam, double phi) {
lp2.phi = phi;
xy1 = imoll_s_forward(lp1, P);
xy2 = imoll_s_forward(lp2, P);
return (xy1.x + xy2.x)/2.;
return (xy1.x + xy2.x) / 2.;
}

PJ *PJ_PROJECTION(imoll) {
Expand Down
6 changes: 3 additions & 3 deletions src/projections/imoll_o.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ pj_imoll_o_compute_zone_offset(struct pj_imoll_o_ns::pj_imoll_o_data *Q,
return (xy2.x + Q->pj[zone2 - 1]->x0) - (xy1.x + Q->pj[zone1 - 1]->x0);
}

static double
pj_imoll_o_compute_zone_x_boundary(PJ *P, double lam, double phi) {
static double pj_imoll_o_compute_zone_x_boundary(PJ *P, double lam,
double phi) {
PJ_LP lp1, lp2;
PJ_XY xy1, xy2;

Expand All @@ -248,7 +248,7 @@ pj_imoll_o_compute_zone_x_boundary(PJ *P, double lam, double phi) {
lp2.phi = phi;
xy1 = imoll_o_s_forward(lp1, P);
xy2 = imoll_o_s_forward(lp2, P);
return (xy1.x + xy2.x)/2.;
return (xy1.x + xy2.x) / 2.;
}

PJ *PJ_PROJECTION(imoll_o) {
Expand Down
4 changes: 2 additions & 2 deletions test/unit/gie_self_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ TEST_F(gieTest, proj_create_crs_to_crs) {

TEST_F(gieTest, proj_create_crs_to_crs_EPSG_4326) {

auto P =
proj_create_crs_to_crs(PJ_DEFAULT_CTX, "EPSG:4326", "EPSG:32631", nullptr);
auto P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "EPSG:4326", "EPSG:32631",
nullptr);
ASSERT_TRUE(P != nullptr);
PJ_COORD a, b;

Expand Down
10 changes: 5 additions & 5 deletions test/unit/test_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5033,7 +5033,7 @@ TEST(wkt_parse, BOUNDCRS_transformation_from_names) {
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(),
projcrs->baseCRS()->nameStr());

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5082,7 +5082,7 @@ TEST(wkt_parse, BOUNDCRS_transformation_from_codes) {
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(),
projcrs->baseCRS()->nameStr());

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5224,7 +5224,7 @@ TEST(wkt_parse, geogcs_TOWGS84_3terms) {
ASSERT_TRUE(crs->transformation()->sourceCRS() != nullptr);
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(), "my GEOGCRS");

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5270,7 +5270,7 @@ TEST(wkt_parse, projcs_TOWGS84_7terms) {
ASSERT_TRUE(crs->transformation()->sourceCRS() != nullptr);
EXPECT_EQ(crs->transformation()->sourceCRS()->nameStr(), "my GEOGCRS");

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
ASSERT_EQ(params.size(), expected.size());
for (int i = 0; i < 7; i++) {
Expand Down Expand Up @@ -5313,7 +5313,7 @@ TEST(io, projcs_TOWGS84_7terms_autocorrect) {
auto crs = nn_dynamic_pointer_cast<BoundCRS>(obj);
ASSERT_TRUE(crs != nullptr);

auto params = crs->transformation()->getTOWGS84Parameters();
auto params = crs->transformation()->getTOWGS84Parameters(true);
auto expected = std::vector<double>{-106.8686, 52.2978, -103.7239, 0.3366,
-0.457, 1.8422, -1.2747};
ASSERT_EQ(params.size(), expected.size());
Expand Down
8 changes: 4 additions & 4 deletions test/unit/test_operation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ TEST(operation, transformation_createGeocentricTranslations) {
2.0, 3.0, std::vector<PositionalAccuracyNNPtr>());
EXPECT_TRUE(transf->validateParameters().empty());

auto params = transf->getTOWGS84Parameters();
auto params = transf->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0};
EXPECT_EQ(params, expected);

Expand All @@ -570,7 +570,7 @@ TEST(operation, transformation_createGeocentricTranslations) {
inv_transf_as_transf->sourceCRS()->nameStr());
auto expected_inv =
std::vector<double>{-1.0, -2.0, -3.0, 0.0, 0.0, 0.0, 0.0};
EXPECT_EQ(inv_transf_as_transf->getTOWGS84Parameters(), expected_inv);
EXPECT_EQ(inv_transf_as_transf->getTOWGS84Parameters(true), expected_inv);

EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=pipeline +step +proj=axisswap +order=2,1 +step "
Expand Down Expand Up @@ -677,7 +677,7 @@ TEST(operation, transformation_createPositionVector) {
ASSERT_EQ(transf->coordinateOperationAccuracies().size(), 1U);

auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
EXPECT_EQ(transf->getTOWGS84Parameters(), expected);
EXPECT_EQ(transf->getTOWGS84Parameters(true), expected);

EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()),
"+proj=pipeline +step +proj=axisswap +order=2,1 +step "
Expand Down Expand Up @@ -744,7 +744,7 @@ TEST(operation, transformation_createCoordinateFrameRotation) {
std::vector<PositionalAccuracyNNPtr>());
EXPECT_TRUE(transf->validateParameters().empty());

auto params = transf->getTOWGS84Parameters();
auto params = transf->getTOWGS84Parameters(true);
auto expected = std::vector<double>{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
EXPECT_EQ(params, expected);

Expand Down