Skip to content

Commit

Permalink
Bugfix: Output coordinate with value of -2^31 correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
joto committed Aug 15, 2017
1 parent 9fd2348 commit d34da40
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/osmium/osm/location.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ DEALINGS IN THE SOFTWARE.
*/

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstring>
Expand Down Expand Up @@ -198,6 +199,12 @@ namespace osmium {
// Convert integer as used by location for coordinates into a string.
template <typename T>
inline T append_location_coordinate_to_string(T iterator, int32_t value) {
// need to special-case this, because later `value = -value` would overflow.
if (value == std::numeric_limits<int32_t>::min()) {
static const char minresult[] = "-214.7483648";
return std::copy_n(minresult, sizeof(minresult) - 1, iterator);
}

// handle negative values
if (value < 0) {
*iterator++ = '-';
Expand Down
16 changes: 16 additions & 0 deletions test/t/osm/test_location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ TEST_CASE("Parsing coordinates from strings") {
C("179.9999999", 1799999999);
C("179.99999999", 1800000000);
C("200.123", 2001230000);
C("214.7483647", 2147483647);

C("8.109E-4" , 8109);
C("8.1090E-4" , 8109);
Expand Down Expand Up @@ -332,6 +333,12 @@ TEST_CASE("Parsing coordinates from strings") {
C("1.1e2:", 1100000000, ":");
}

TEST_CASE("Parsing min coordinate from string") {
const char* minval = "-214.7483648";
const char** data = &minval;
REQUIRE(osmium::detail::string_to_location_coordinate(data) == -2147483648l);
}

TEST_CASE("Writing zero coordinate into string") {
std::string buffer;
osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), 0);
Expand Down Expand Up @@ -369,6 +376,15 @@ TEST_CASE("Writing coordinate into string") {
CW( 40101010, "4.010101");
CW( 494561234, "49.4561234");
CW(1799999999, "179.9999999");

CW(2147483647, "214.7483647");
}

TEST_CASE("Writing min coordinate into string") {
std::string buffer;

osmium::detail::append_location_coordinate_to_string(std::back_inserter(buffer), -2147483648l);
REQUIRE(buffer == "-214.7483648");
}

TEST_CASE("set lon/lat from string") {
Expand Down

0 comments on commit d34da40

Please sign in to comment.