diff options
| -rw-r--r-- | src/iso19111/common.cpp | 15 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 16 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 58 |
3 files changed, 78 insertions, 11 deletions
diff --git a/src/iso19111/common.cpp b/src/iso19111/common.cpp index 57654d84..bdd836e1 100644 --- a/src/iso19111/common.cpp +++ b/src/iso19111/common.cpp @@ -172,21 +172,22 @@ void UnitOfMeasure::_exportToWKT( { const bool isWKT2 = formatter->version() == WKTFormatter::Version::WKT2; - if (formatter->forceUNITKeyword() && type() != Type::PARAMETRIC) { + const auto l_type = type(); + if (formatter->forceUNITKeyword() && l_type != Type::PARAMETRIC) { formatter->startNode(WKTConstants::UNIT, !codeSpace().empty()); } else if (!unitType.empty()) { formatter->startNode(unitType, !codeSpace().empty()); } else { - if (isWKT2 && type() == Type::LINEAR) { + if (isWKT2 && l_type == Type::LINEAR) { formatter->startNode(WKTConstants::LENGTHUNIT, !codeSpace().empty()); - } else if (isWKT2 && type() == Type::ANGULAR) { + } else if (isWKT2 && l_type == Type::ANGULAR) { formatter->startNode(WKTConstants::ANGLEUNIT, !codeSpace().empty()); - } else if (isWKT2 && type() == Type::SCALE) { + } else if (isWKT2 && l_type == Type::SCALE) { formatter->startNode(WKTConstants::SCALEUNIT, !codeSpace().empty()); - } else if (isWKT2 && type() == Type::TIME) { + } else if (isWKT2 && l_type == Type::TIME) { formatter->startNode(WKTConstants::TIMEUNIT, !codeSpace().empty()); - } else if (isWKT2 && type() == Type::PARAMETRIC) { + } else if (isWKT2 && l_type == Type::PARAMETRIC) { formatter->startNode(WKTConstants::PARAMETRICUNIT, !codeSpace().empty()); } else { @@ -211,7 +212,7 @@ void UnitOfMeasure::_exportToWKT( formatter->addQuotedString(l_name); } const auto &factor = conversionToSI(); - if (!isWKT2 || factor != 0.0) { + if (!isWKT2 || l_type != Type::TIME || factor != 0.0) { // Some TIMEUNIT do not have a conversion factor formatter->add(factor); } diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 6f9b6283..8a10bc5a 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -2147,11 +2147,19 @@ void ParameterValue::_exportToWKT(io::WKTFormatter *formatter) const { // registered linear / angular unit. const auto &unitType = unit.type(); if (unitType == common::UnitOfMeasure::Type::LINEAR) { - formatter->add( - l_value.convertToUnit(*(formatter->axisLinearUnit()))); + const auto &targetUnit = *(formatter->axisLinearUnit()); + if (targetUnit.conversionToSI() == 0.0) { + throw io::FormattingException( + "cannot convert value to target linear unit"); + } + formatter->add(l_value.convertToUnit(targetUnit)); } else if (unitType == common::UnitOfMeasure::Type::ANGULAR) { - formatter->add( - l_value.convertToUnit(*(formatter->axisAngularUnit()))); + const auto &targetUnit = *(formatter->axisAngularUnit()); + if (targetUnit.conversionToSI() == 0.0) { + throw io::FormattingException( + "cannot convert value to target angular unit"); + } + formatter->add(l_value.convertToUnit(targetUnit)); } else { formatter->add(l_value.getSIValue()); } diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 157614b4..69ef9073 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -8965,3 +8965,61 @@ TEST(wkt_export, precision) { WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()), wkt); } + +// --------------------------------------------------------------------------- + +// Avoid division by zero + +TEST(wkt_export, invalid_linear_unit) { + auto wkt = "PROJCS[\"WGS 84 / UTM zone 31N\",\n" + " GEOGCS[\"WGS 84\",\n" + " DATUM[\"WGS_1984\",\n" + " SPHEROID[\"WGS 84\",6378137,298.257223563]],\n" + " PRIMEM[\"Greenwich\",0],\n" + " UNIT[\"degree\",0.0174532925199433]],\n" + " PROJECTION[\"Transverse_Mercator\"],\n" + " PARAMETER[\"latitude_of_origin\",0],\n" + " PARAMETER[\"central_meridian\",3],\n" + " PARAMETER[\"scale_factor\",0.9996],\n" + " PARAMETER[\"false_easting\",500000],\n" + " PARAMETER[\"false_northing\",0],\n" + " UNIT[\"foo\",0]]"; + + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); + ASSERT_TRUE(crs != nullptr); + + EXPECT_THROW( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()), + FormattingException); +} + +// --------------------------------------------------------------------------- + +// Avoid division by zero + +TEST(wkt_export, invalid_angular_unit) { + auto wkt = "PROJCS[\"WGS 84 / UTM zone 31N\",\n" + " GEOGCS[\"WGS 84\",\n" + " DATUM[\"WGS_1984\",\n" + " SPHEROID[\"WGS 84\",6378137,298.257223563]],\n" + " PRIMEM[\"Greenwich\",0],\n" + " UNIT[\"foo\",0]],\n" + " PROJECTION[\"Transverse_Mercator\"],\n" + " PARAMETER[\"latitude_of_origin\",0],\n" + " PARAMETER[\"central_meridian\",3],\n" + " PARAMETER[\"scale_factor\",0.9996],\n" + " PARAMETER[\"false_easting\",500000],\n" + " PARAMETER[\"false_northing\",0],\n" + " UNIT[\"meter\",1]]"; + + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); + ASSERT_TRUE(crs != nullptr); + + EXPECT_THROW( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()), + FormattingException); +} |
