Skip to content

Commit

Permalink
Bugfix: Terminate called on full buffer.
Browse files Browse the repository at this point in the history
A full non-auto-growing buffer could lead to the program terminating
instead of a thrown exception. Reason was that the number of bytes
written to the buffer was not tracked properly when appending tag keys
and values to the buffer. The destructor on the TagListBuilder would
then throw another exception which terminates the program. This should
fix this problem by keeping the number of bytes written to the buffer
correctly.

See #189.
  • Loading branch information
joto committed Jan 26, 2017
1 parent a427298 commit d1c3788
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
18 changes: 17 additions & 1 deletion include/osmium/builder/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,20 @@ namespace osmium {
return length;
}

/**
* Append data to buffer and append an additional \0.
*
* @param data Pointer to data.
* @param length Length of data in bytes.
* @returns The number of bytes appended (length + 1).
*/
osmium::memory::item_size_type append_with_zero(const char* data, const osmium::memory::item_size_type length) {
unsigned char* target = reserve_space(length + 1);
std::copy_n(reinterpret_cast<const unsigned char*>(data), length, target);
target[length] = '\0';
return length + 1;
}

/**
* Append \0-terminated string to buffer.
*
Expand All @@ -180,9 +194,11 @@ namespace osmium {
/**
* Append '\0' to the buffer.
*
* @deprecated Use append_with_zero() instead.
*
* @returns The number of bytes appended (always 1).
*/
osmium::memory::item_size_type append_zero() {
OSMIUM_DEPRECATED osmium::memory::item_size_type append_zero() {
*reserve_space(1) = '\0';
return 1;
}
Expand Down
20 changes: 11 additions & 9 deletions include/osmium/builder/osm_object_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ namespace osmium {
if (std::strlen(value) > osmium::max_osm_string_length) {
throw std::length_error("OSM tag value is too long");
}
add_size(append(key) + append(value));
add_size(append(key));
add_size(append(value));
}

/**
Expand All @@ -117,8 +118,8 @@ namespace osmium {
if (value_length > osmium::max_osm_string_length) {
throw std::length_error("OSM tag value is too long");
}
add_size(append(key, osmium::memory::item_size_type(key_length)) + append_zero() +
append(value, osmium::memory::item_size_type(value_length)) + append_zero());
add_size(append_with_zero(key, osmium::memory::item_size_type(key_length)));
add_size(append_with_zero(value, osmium::memory::item_size_type(value_length)));
}

/**
Expand All @@ -134,8 +135,8 @@ namespace osmium {
if (value.size() > osmium::max_osm_string_length) {
throw std::length_error("OSM tag value is too long");
}
add_size(append(key.data(), osmium::memory::item_size_type(key.size()) + 1) +
append(value.data(), osmium::memory::item_size_type(value.size()) + 1));
add_size(append(key.data(), osmium::memory::item_size_type(key.size()) + 1));
add_size(append(value.data(), osmium::memory::item_size_type(value.size()) + 1));
}

/**
Expand All @@ -144,7 +145,8 @@ namespace osmium {
* @param tag Tag.
*/
void add_tag(const osmium::Tag& tag) {
add_size(append(tag.key()) + append(tag.value()));
add_size(append(tag.key()));
add_size(append(tag.value()));
}

/**
Expand Down Expand Up @@ -226,7 +228,7 @@ namespace osmium {
throw std::length_error("OSM relation member role is too long");
}
member.set_role_size(osmium::string_size_type(length) + 1);
add_size(append(role, osmium::memory::item_size_type(length)) + append_zero());
add_size(append_with_zero(role, osmium::memory::item_size_type(length)));
add_padding(true);
}

Expand Down Expand Up @@ -310,7 +312,7 @@ namespace osmium {
throw std::length_error("OSM user name is too long");
}
comment.set_user_size(osmium::string_size_type(length) + 1);
add_size(append(user, osmium::memory::item_size_type(length)) + append_zero());
add_size(append_with_zero(user, osmium::memory::item_size_type(length)));
}

void add_text(osmium::ChangesetComment& comment, const char* text, const size_t length) {
Expand All @@ -322,7 +324,7 @@ namespace osmium {
throw std::length_error("OSM changeset comment is too long");
}
comment.set_text_size(osmium::string_size_type(length) + 1);
add_size(append(text, osmium::memory::item_size_type(length)) + append_zero());
add_size(append_with_zero(text, osmium::memory::item_size_type(length)));
add_padding(true);
}

Expand Down

0 comments on commit d1c3788

Please sign in to comment.