Skip to content
Commits on Source (4)
......@@ -13,6 +13,24 @@ This project adheres to [Semantic Versioning](https://semver.org/).
### Fixed
## [2.15.3] - 2019-09-16
### Added
* New header option "sorting" when reading and writing PBFs. If the header
option "sorting" is set to `Type_then_ID`, the optional header property
`Sort.Type_then_ID` is set on writing to PBF files. When reading PBF files
with this header property, the "sorting" header option is set accordingly.
### Fixed
* Do not propagate C++ exception through C code. We are using the Expat
XML parser, a C library. It calls callbacks in our code. When those
callbacks throw, the exception was propagated through the C code. This
did work in the tests, but that behaviour isn't guaranteed (C++
standard says it is implementation defined). This fixes it by catching
the exception and rethrowing it later.
## [2.15.2] - 2019-08-16
### Added
......@@ -956,7 +974,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
Doxygen (up to version 1.8.8). This version contains a workaround to fix
this.
[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.2...HEAD
[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.3...HEAD
[2.15.3]: https://github.com/osmcode/libosmium/compare/v2.15.2...v2.15.3
[2.15.2]: https://github.com/osmcode/libosmium/compare/v2.15.1...v2.15.2
[2.15.1]: https://github.com/osmcode/libosmium/compare/v2.15.0...v2.15.1
[2.15.0]: https://github.com/osmcode/libosmium/compare/v2.14.2...v2.15.0
......
......@@ -40,7 +40,7 @@ project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
set(LIBOSMIUM_VERSION_MINOR 15)
set(LIBOSMIUM_VERSION_PATCH 2)
set(LIBOSMIUM_VERSION_PATCH 3)
set(LIBOSMIUM_VERSION
"${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
......
libosmium (2.15.3-1) unstable; urgency=medium
* New upstream release.
-- Bas Couwenberg <sebastic@debian.org> Tue, 17 Sep 2019 05:54:40 +0200
libosmium (2.15.2-1) unstable; urgency=medium
* New upstream release.
......
......@@ -847,8 +847,13 @@ namespace osmium {
}
}
break;
case protozero::tag_and_type(OSMFormat::HeaderBlock::repeated_string_optional_features, protozero::pbf_wire_type::length_delimited):
header.set("pbf_optional_feature_" + std::to_string(i++), pbf_header_block.get_string());
case protozero::tag_and_type(OSMFormat::HeaderBlock::repeated_string_optional_features, protozero::pbf_wire_type::length_delimited): {
const auto opt = pbf_header_block.get_string();
header.set("pbf_optional_feature_" + std::to_string(i++), opt);
if (opt == "Sort.Type_then_ID") {
header.set("sorting", "Type_then_ID");
}
}
break;
case protozero::tag_and_type(OSMFormat::HeaderBlock::optional_string_writingprogram, protozero::pbf_wire_type::length_delimited):
header.set("generator", pbf_header_block.get_string());
......
......@@ -577,6 +577,10 @@ namespace osmium {
pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_optional_features, "LocationsOnWays");
}
if (header.get("sorting") == "Type_then_ID") {
pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_optional_features, "Sort.Type_then_ID");
}
pbf_header_block.add_string(OSMFormat::HeaderBlock::optional_string_writingprogram, header.get("generator"));
const std::string osmosis_replication_timestamp{header.get("osmosis_replication_timestamp")};
......
......@@ -60,6 +60,7 @@ DEALINGS IN THE SOFTWARE.
#include <cassert>
#include <cstring>
#include <exception>
#include <future>
#include <limits>
#include <memory>
......@@ -177,17 +178,44 @@ namespace osmium {
class ExpatXMLParser {
XML_Parser m_parser;
std::exception_ptr m_exception_ptr{};
static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) {
static_cast<XMLParser*>(data)->start_element(element, attrs);
template <typename TFunc>
void member_wrap(XMLParser& xml_parser, TFunc&& func) noexcept {
if (m_exception_ptr) {
return;
}
try {
std::forward<TFunc>(func)(xml_parser);
} catch (...) {
m_exception_ptr = std::current_exception();
XML_StopParser(m_parser, 0);
}
}
static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) {
static_cast<XMLParser*>(data)->end_element(element);
template <typename TFunc>
static void wrap(void* data, TFunc&& func) noexcept {
assert(data);
auto& xml_parser = *static_cast<XMLParser*>(data);
xml_parser.m_expat_xml_parser->member_wrap(xml_parser, std::forward<TFunc>(func));
}
static void XMLCALL character_data_wrapper(void* data, const XML_Char* text, int len) {
static_cast<XMLParser*>(data)->characters(text, len);
static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) noexcept {
wrap(data, [&](XMLParser& xml_parser) {
xml_parser.start_element(element, attrs);
});
}
static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) noexcept {
wrap(data, [&](XMLParser& xml_parser) {
xml_parser.end_element(element);
});
}
static void XMLCALL character_data_wrapper(void* data, const XML_Char* text, int len) noexcept {
wrap(data, [&](XMLParser& xml_parser) {
xml_parser.characters(text, len);
});
}
// This handler is called when there are any XML entities
......@@ -195,7 +223,7 @@ namespace osmium {
// but they can be misused. See
// https://en.wikipedia.org/wiki/Billion_laughs
// The handler will just throw an error.
static void entity_declaration_handler(void* /*userData*/,
static void entity_declaration_handler(void* data,
const XML_Char* /*entityName*/,
int /*is_parameter_entity*/,
const XML_Char* /*value*/,
......@@ -203,8 +231,10 @@ namespace osmium {
const XML_Char* /*base*/,
const XML_Char* /*systemId*/,
const XML_Char* /*publicId*/,
const XML_Char* /*notationName*/) {
const XML_Char* /*notationName*/) noexcept {
wrap(data, [&](XMLParser& /*xml_parser*/) {
throw osmium::xml_error{"XML entities are not supported"};
});
}
public:
......@@ -233,12 +263,17 @@ namespace osmium {
void operator()(const std::string& data, bool last) {
assert(data.size() < std::numeric_limits<int>::max());
if (XML_Parse(m_parser, data.data(), static_cast<int>(data.size()), last) == XML_STATUS_ERROR) {
if (m_exception_ptr) {
std::rethrow_exception(m_exception_ptr);
}
throw osmium::xml_error{m_parser};
}
}
}; // class ExpatXMLParser
ExpatXMLParser* m_expat_xml_parser{nullptr};
template <typename T>
static void check_attributes(const XML_Char** attrs, T&& check) {
while (*attrs) {
......@@ -739,6 +774,7 @@ namespace osmium {
osmium::thread::set_thread_name("_osmium_xml_in");
ExpatXMLParser parser{this};
m_expat_xml_parser = &parser;
while (!input_done()) {
const std::string data{get_input()};
......
......@@ -35,8 +35,8 @@ DEALINGS IN THE SOFTWARE.
#define LIBOSMIUM_VERSION_MAJOR 2
#define LIBOSMIUM_VERSION_MINOR 15
#define LIBOSMIUM_VERSION_PATCH 2
#define LIBOSMIUM_VERSION_PATCH 3
#define LIBOSMIUM_VERSION_STRING "2.15.2"
#define LIBOSMIUM_VERSION_STRING "2.15.3"
#endif // OSMIUM_VERSION_HPP