Skip to content

Commit f8cad73

Browse files
committed
gazetteer: parse full admin_level string only
atoi only parses a string to the first non-digit with the result that fractions like 2.5 end up being parsed despite not being a correct integer. Use strtol instead to check that the whole string gets parsed.
1 parent be022b8 commit f8cad73

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

src/gazetteer-style.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,13 @@ void gazetteer_style_t::process_tags(osmium::OSMObject const &o)
308308
char const *const v = item.value();
309309

310310
if (std::strcmp(k, "admin_level") == 0) {
311-
m_admin_level = std::atoi(v);
312-
if (m_admin_level <= 0 || m_admin_level > MAX_ADMINLEVEL) {
311+
char *endp = nullptr;
312+
errno = 0;
313+
auto const parsed = std::strtol(v, &endp, 10);
314+
if (errno == 0 && *endp == '\0' && parsed > 0 &&
315+
parsed < MAX_ADMINLEVEL) {
316+
m_admin_level = static_cast<int>(parsed);
317+
} else {
313318
m_admin_level = MAX_ADMINLEVEL;
314319
}
315320
continue;

tests/test-output-gazetteer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ TEST_CASE("Admin levels")
697697
t.add(9003, "place=city,admin_level=x");
698698
t.add(9004, "place=city,admin_level=1");
699699
t.add(9005, "place=city,admin_level=0");
700+
t.add(9006, "place=city,admin_level=2.5");
700701

701702
t.import();
702703

@@ -707,6 +708,7 @@ TEST_CASE("Admin levels")
707708
CHECK("15" == t.obj_field(conn, 9003, "place", "admin_level"));
708709
CHECK("1" == t.obj_field(conn, 9004, "place", "admin_level"));
709710
CHECK("15" == t.obj_field(conn, 9005, "place", "admin_level"));
711+
CHECK("15" == t.obj_field(conn, 9006, "place", "admin_level"));
710712
}
711713

712714
TEST_CASE("Administrative boundaries with place tags")

0 commit comments

Comments
 (0)