Skip to content

Commit 99c8070

Browse files
committed
Cleanup code using fixed-size array in middle-pgsql
1 parent ab21493 commit 99c8070

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

src/middle-pgsql.cpp

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,41 +105,56 @@ void middle_pgsql_t::table_desc::build_index(std::string const &conninfo) const
105105
db_connection.exec(m_create_fw_dep_indexes);
106106
}
107107

108-
namespace {
109-
// Decodes a portion of an array literal from postgres */
110-
// Argument should point to beginning of literal, on return points to delimiter */
111-
inline char const *decode_upto(char const *src, char *dst)
108+
/**
109+
* Decode item in an array literal from PostgreSQL to the next delimiter.
110+
*
111+
* \param src Pointer to the text with the array literal.
112+
* \param dst The decoded item is written to this string. The string is
113+
* cleared before use.
114+
* \returns Pointer to the delimiter found.
115+
* \throws runtime_error If the input string ends before the delimiter is found.
116+
*/
117+
static char const *decode_to_delimiter(char const *src, std::string *dst)
112118
{
119+
assert(src);
120+
dst->clear();
121+
113122
bool const quoted = (*src == '"');
114123
if (quoted) {
115124
++src;
116125
}
117126

118127
while (quoted ? (*src != '"') : (*src != ',' && *src != '}')) {
128+
if (*src == '\0') {
129+
throw std::runtime_error{
130+
"Parsing array literal from database failed."};
131+
}
119132
if (*src == '\\') {
120133
switch (src[1]) {
121134
case 'n':
122-
*dst++ = '\n';
135+
dst->append(1, '\n');
123136
break;
124137
case 't':
125-
*dst++ = '\t';
138+
dst->append(1, '\t');
126139
break;
127140
default:
128-
*dst++ = src[1];
141+
dst->append(1, src[1]);
129142
break;
130143
}
131144
src += 2;
132145
} else {
133-
*dst++ = *src++;
146+
dst->append(1, *src++);
134147
}
135148
}
149+
136150
if (quoted) {
137151
++src;
138152
}
139-
*dst = 0;
153+
140154
return src;
141155
}
142156

157+
namespace {
143158
template <typename T>
144159
void pgsql_parse_tags(char const *string, osmium::memory::Buffer *buffer,
145160
T *obuilder)
@@ -148,15 +163,15 @@ void pgsql_parse_tags(char const *string, osmium::memory::Buffer *buffer,
148163
return;
149164
}
150165

151-
char key[1024];
152-
char val[1024];
153166
osmium::builder::TagListBuilder builder{*buffer, obuilder};
154167

168+
std::string key;
169+
std::string val;
155170
while (*string != '}') {
156-
string = decode_upto(string, key);
171+
string = decode_to_delimiter(string, &key);
157172
// String points to the comma */
158173
++string;
159-
string = decode_upto(string, val);
174+
string = decode_to_delimiter(string, &val);
160175
builder.add_tag(key, val);
161176
// String points to the comma or closing '}' */
162177
if (*string == ',') {
@@ -172,15 +187,15 @@ void pgsql_parse_members(char const *string, osmium::memory::Buffer *buffer,
172187
return;
173188
}
174189

175-
char role[1024];
190+
std::string role;
176191
osmium::builder::RelationMemberListBuilder builder{*buffer, obuilder};
177192

178193
while (*string != '}') {
179194
char type = string[0];
180195
char *endp = nullptr;
181196
osmid_t id = std::strtoll(string + 1, &endp, 10);
182197
// String points to the comma */
183-
string = decode_upto(endp + 1, role);
198+
string = decode_to_delimiter(endp + 1, &role);
184199
builder.add_member(osmium::char_to_item_type(type), id, role);
185200
// String points to the comma or closing '}' */
186201
if (*string == ',') {

0 commit comments

Comments
 (0)