|
7 | 7 | #include <mpd/recv.h> |
8 | 8 | #include "internal.h" |
9 | 9 | #include "request.h" |
| 10 | +#include "quote.h" |
10 | 11 | #include "iso8601.h" |
11 | 12 | #include "check_tag.h" |
12 | 13 |
|
@@ -92,25 +93,34 @@ mpd_search_add_constraint(struct mpd_connection *connection, |
92 | 93 | assert(name != NULL); |
93 | 94 | assert(value != NULL); |
94 | 95 |
|
95 | | - char *arg = mpd_sanitize_arg(value); |
96 | | - if (arg == NULL) { |
97 | | - mpd_error_code(&connection->error, MPD_ERROR_OOM); |
| 96 | + const size_t name_length = strlen(name); |
| 97 | + |
| 98 | + /* worst-case allocation */ |
| 99 | + const size_t size = 1 + name_length + 2 + strlen(value) * 2 + 2; |
| 100 | + char *p = mpd_request_prepare_append(connection, size); |
| 101 | + if (p == NULL) |
98 | 102 | return false; |
99 | | - } |
100 | 103 |
|
101 | | - const size_t add_length = 1 + strlen(name) + 2 + strlen(arg) + 1; |
| 104 | + char *const end = p + size - 1; |
| 105 | + |
| 106 | + *p++ = ' '; |
| 107 | + |
| 108 | + memcpy(p, name, name_length); |
| 109 | + p += name_length; |
| 110 | + |
| 111 | + *p++ = ' '; |
102 | 112 |
|
103 | | - char *dest = mpd_request_prepare_append(connection, add_length); |
104 | | - if (dest == NULL) { |
105 | | - free(arg); |
| 113 | + p = quote(p, end, value); |
| 114 | + if (p == NULL) { |
| 115 | + mpd_error_code(&connection->error, MPD_ERROR_ARGUMENT); |
| 116 | + mpd_error_message(&connection->error, "bad string"); |
106 | 117 | return false; |
107 | 118 | } |
108 | 119 |
|
109 | | - sprintf(dest, " %s \"%s\"", name, arg); |
110 | | - |
111 | | - free(arg); |
| 120 | + *p = '\0'; |
112 | 121 | return true; |
113 | 122 | } |
| 123 | + |
114 | 124 | bool |
115 | 125 | mpd_search_add_base_constraint(struct mpd_connection *connection, |
116 | 126 | enum mpd_operator oper, |
@@ -191,23 +201,24 @@ mpd_search_add_expression(struct mpd_connection *connection, |
191 | 201 | assert(connection != NULL); |
192 | 202 | assert(expression != NULL); |
193 | 203 |
|
194 | | - char *arg = mpd_sanitize_arg(expression); |
195 | | - if (arg == NULL) { |
196 | | - mpd_error_code(&connection->error, MPD_ERROR_OOM); |
| 204 | + /* worst-case allocation */ |
| 205 | + const size_t size = 2 + strlen(expression) * 2 + 2; |
| 206 | + char *p = mpd_request_prepare_append(connection, size); |
| 207 | + if (p == NULL) |
197 | 208 | return false; |
198 | | - } |
199 | 209 |
|
200 | | - const size_t add_length = 2 + strlen(arg) + 1; |
| 210 | + char *const end = p + size - 1; |
| 211 | + |
| 212 | + *p++ = ' '; |
201 | 213 |
|
202 | | - char *dest = mpd_request_prepare_append(connection, add_length); |
203 | | - if (dest == NULL) { |
204 | | - free(arg); |
| 214 | + p = quote(p, end, expression); |
| 215 | + if (p == NULL) { |
| 216 | + mpd_error_code(&connection->error, MPD_ERROR_ARGUMENT); |
| 217 | + mpd_error_message(&connection->error, "bad string"); |
205 | 218 | return false; |
206 | 219 | } |
207 | 220 |
|
208 | | - sprintf(dest, " \"%s\"", arg); |
209 | | - |
210 | | - free(arg); |
| 221 | + *p = '\0'; |
211 | 222 | return true; |
212 | 223 | } |
213 | 224 |
|
@@ -306,22 +317,31 @@ mpd_search_add_db_songs_to_playlist(struct mpd_connection *connection, |
306 | 317 | if (!mpd_request_begin(connection)) |
307 | 318 | return false; |
308 | 319 |
|
309 | | - char *arg = mpd_sanitize_arg(playlist_name); |
310 | | - if (arg == NULL) { |
311 | | - mpd_error_code(&connection->error, MPD_ERROR_OOM); |
312 | | - return false; |
313 | | - } |
| 320 | + static const char *const prefix = "searchaddpl "; |
| 321 | + const size_t prefix_length = strlen(prefix); |
314 | 322 |
|
315 | | - const size_t len = 15 + strlen(arg) + 2; |
316 | | - connection->request = malloc(len); |
| 323 | + /* worst-case allocation */ |
| 324 | + const size_t size = prefix_length + 1 + strlen(playlist_name) * 2 + 3; |
| 325 | + char *p = connection->request = malloc(size); |
317 | 326 | if (connection->request == NULL) { |
318 | | - free(arg); |
319 | 327 | mpd_error_code(&connection->error, MPD_ERROR_OOM); |
320 | 328 | return false; |
321 | 329 | } |
322 | 330 |
|
323 | | - snprintf(connection->request, len, "searchaddpl \"%s\" ", arg); |
| 331 | + char *const end = p + size - 1; |
| 332 | + |
| 333 | + memcpy(p, prefix, prefix_length); |
| 334 | + p += prefix_length; |
| 335 | + |
| 336 | + p = quote(p, end, playlist_name); |
| 337 | + if (p == NULL) { |
| 338 | + mpd_request_cancel(connection); |
| 339 | + mpd_error_code(&connection->error, MPD_ERROR_ARGUMENT); |
| 340 | + mpd_error_message(&connection->error, "bad string"); |
| 341 | + return false; |
| 342 | + } |
324 | 343 |
|
325 | | - free(arg); |
| 344 | + *p++ = ' '; |
| 345 | + *p = '\0'; |
326 | 346 | return true; |
327 | 347 | } |
0 commit comments