Skip to content

Commit e378060

Browse files
committed
Clean up ewkb::parser_t and check for buffer overflow
The old version didn't check that it didn't read outside the buffer.
1 parent a8be107 commit e378060

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

src/wkb.hpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -278,20 +278,20 @@ class parser_t
278278
return out;
279279
}
280280

281-
explicit parser_t(char const *wkb) : m_wkb(wkb), m_pos(0) {}
282-
explicit parser_t(std::string const &wkb) : m_wkb(wkb.c_str()), m_pos(0) {}
281+
explicit parser_t(std::string const &wkb) noexcept : m_wkb(&wkb) {}
283282

284-
size_t save_pos() const { return m_pos; }
285-
void rewind(size_t pos) { m_pos = pos; }
283+
std::size_t save_pos() const noexcept { return m_pos; }
286284

287-
int read_header()
285+
void rewind(std::size_t pos) noexcept { m_pos = pos; }
286+
287+
uint32_t read_header()
288288
{
289-
m_pos += sizeof(uint8_t); // skip endianess
289+
m_pos += sizeof(uint8_t); // skip endianess marker
290290

291291
auto const type = read_data<uint32_t>();
292292

293293
if (type & wkb_srid) {
294-
m_pos += sizeof(int); // skip srid
294+
m_pos += sizeof(uint32_t); // skip SRID
295295
}
296296

297297
return type & 0xffU;
@@ -307,7 +307,12 @@ class parser_t
307307
return osmium::geom::Coordinates{x, y};
308308
}
309309

310-
void skip_points(size_t num) { m_pos += sizeof(double) * 2 * num; }
310+
void skip_points(std::size_t num)
311+
{
312+
auto const length = sizeof(double) * 2 * num;
313+
check_available(length);
314+
m_pos += length;
315+
}
311316

312317
template <typename PROJ>
313318
double get_area(PROJ *proj = nullptr)
@@ -388,18 +393,27 @@ class parser_t
388393
return std::abs(total) * 0.5;
389394
}
390395

396+
void check_available(std::size_t length)
397+
{
398+
if (m_pos + length > m_wkb->size()) {
399+
throw std::runtime_error{"Invalid EWKB geometry found"};
400+
}
401+
}
402+
391403
template <typename T>
392404
T read_data()
393405
{
406+
check_available(sizeof(T));
407+
394408
T data;
395-
memcpy(&data, m_wkb + m_pos, sizeof(T));
409+
std::memcpy(&data, m_wkb->data() + m_pos, sizeof(T));
396410
m_pos += sizeof(T);
397411

398412
return data;
399413
}
400414

401-
char const *m_wkb;
402-
size_t m_pos;
415+
std::string const *m_wkb;
416+
std::size_t m_pos = 0;
403417
};
404418

405419
} // namespace ewkb

0 commit comments

Comments
 (0)