Skip to content

Commit f17bd7a

Browse files
committed
Bugfix: OPL parser stumbled on "%%" in text
In this case a zero character (`\0`) was inserted into the text, but that's not an allowed UTF-8 character. The fix now inserts a `%` instead. Fixes #328.
1 parent f8d0313 commit f17bd7a

3 files changed

Lines changed: 12 additions & 2 deletions

File tree

include/osmium/io/detail/opl_parser_functions.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ namespace osmium {
144144
* Returns a pointer to next character that needs to be consumed.
145145
*/
146146
inline void opl_parse_escaped(const char** data, std::string& result) {
147+
assert(data);
148+
assert(*data);
147149
const char* s = *data;
148150
uint32_t value = 0;
149151
const int max_length = sizeof(value) * 2 /* hex chars per byte */;
@@ -154,7 +156,11 @@ namespace osmium {
154156
}
155157
if (*s == '%') {
156158
++s;
157-
append_codepoint_as_utf8(value, std::back_inserter(result));
159+
if (value == 0) {
160+
result += '%';
161+
} else {
162+
append_codepoint_as_utf8(value, std::back_inserter(result));
163+
}
158164
*data = s;
159165
return;
160166
}
@@ -182,6 +188,8 @@ namespace osmium {
182188
* Returns a pointer to next character that needs to be consumed.
183189
*/
184190
inline void opl_parse_string(const char** data, std::string& result) {
191+
assert(data);
192+
assert(*data);
185193
const char* s = *data;
186194
while (true) {
187195
if (*s == '\0' || *s == ' ' || *s == '\t' || *s == ',' || *s == '=') {

include/osmium/io/detail/string_util.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ namespace osmium {
203203

204204
inline void append_utf8_encoded_string(std::string& out, const char* data) {
205205
static const char* lookup_hex = "0123456789abcdef";
206+
assert(data);
206207
const char* end_ptr = data + std::strlen(data);
207208

208209
while (data != end_ptr) {
@@ -236,6 +237,7 @@ namespace osmium {
236237
}
237238

238239
inline void append_xml_encoded_string(std::string& out, const char* data) {
240+
assert(data);
239241
for (; *data != '\0'; ++data) {
240242
switch (*data) {
241243
case '&': out += "&"; break;

test/t/io/test_opl_parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ TEST_CASE("Parse OPL: parse escaped") {
104104
const char* e = s + std::strlen(s);
105105
oid::opl_parse_escaped(&s, result);
106106
REQUIRE(result.size() == 1);
107-
REQUIRE(result[0] == '\0');
107+
REQUIRE(result[0] == '%');
108108
REQUIRE(s == e);
109109
}
110110

0 commit comments

Comments
 (0)