diff options
Diffstat (limited to 'libmailutils/url/create.c')
-rw-r--r-- | libmailutils/url/create.c | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/libmailutils/url/create.c b/libmailutils/url/create.c index e58064081..130b7a2bc 100644 --- a/libmailutils/url/create.c +++ b/libmailutils/url/create.c | |||
@@ -59,9 +59,9 @@ getkn (struct mu_url_ctx *ctx, char *delim) | |||
59 | size_t n; | 59 | size_t n; |
60 | 60 | ||
61 | if (*ctx->cur == 0) | 61 | if (*ctx->cur == 0) |
62 | return -1; | 62 | return MU_ERR_PARSE; |
63 | n = strcspn (ctx->cur, delim); | 63 | n = strcspn (ctx->cur, delim); |
64 | if (n > ctx->toksize) | 64 | if (n + 1 > ctx->toksize) |
65 | { | 65 | { |
66 | char *p = realloc (ctx->tokbuf, n + 1); | 66 | char *p = realloc (ctx->tokbuf, n + 1); |
67 | if (!p) | 67 | if (!p) |
@@ -220,11 +220,28 @@ _mu_url_ctx_parse_host (struct mu_url_ctx *ctx, int has_host) | |||
220 | int rc; | 220 | int rc; |
221 | mu_url_t url = ctx->url; | 221 | mu_url_t url = ctx->url; |
222 | 222 | ||
223 | rc = getkn (ctx, ":/;?"); | 223 | rc = getkn (ctx, "[:/;?"); |
224 | if (rc) | 224 | if (rc) |
225 | return rc; | 225 | return rc; |
226 | 226 | ||
227 | if (ctx->toklen) | 227 | if (*ctx->cur == '[') |
228 | { | ||
229 | /* Possibly IPv6 address */ | ||
230 | rc = getkn (ctx, "]/;?"); | ||
231 | if (rc) | ||
232 | return rc; | ||
233 | if (*ctx->cur == ']') | ||
234 | { | ||
235 | ctx->cur++; | ||
236 | rc = str_assign (&url->host, ctx->tokbuf + 1); | ||
237 | if (rc) | ||
238 | return rc; | ||
239 | url->flags |= MU_URL_HOST | MU_URL_IPV6; | ||
240 | has_host = 1; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | if (!(url->flags & MU_URL_HOST) && ctx->toklen) | ||
228 | { | 245 | { |
229 | rc = str_assign (&url->host, ctx->tokbuf); | 246 | rc = str_assign (&url->host, ctx->tokbuf); |
230 | if (rc) | 247 | if (rc) |
@@ -232,22 +249,20 @@ _mu_url_ctx_parse_host (struct mu_url_ctx *ctx, int has_host) | |||
232 | url->flags |= MU_URL_HOST; | 249 | url->flags |= MU_URL_HOST; |
233 | has_host = 1; | 250 | has_host = 1; |
234 | } | 251 | } |
235 | 252 | ||
236 | if (*ctx->cur == ':') | 253 | if (*ctx->cur == ':') |
237 | { | 254 | { |
238 | ctx->cur++; | ||
239 | has_host = 1; | 255 | has_host = 1; |
240 | 256 | ctx->cur++; | |
241 | rc = getkn (ctx, "/;?"); | 257 | rc = getkn (ctx, ":/;?"); |
242 | if (rc) | 258 | if (rc) |
243 | return rc; | 259 | return rc; |
244 | |||
245 | rc = str_assign (&url->portstr, ctx->tokbuf); | 260 | rc = str_assign (&url->portstr, ctx->tokbuf); |
246 | if (rc) | 261 | if (rc) |
247 | return rc; | 262 | return rc; |
248 | url->flags |= MU_URL_PORT; | 263 | url->flags |= MU_URL_PORT; |
249 | } | 264 | } |
250 | 265 | ||
251 | if (*ctx->cur == '/') | 266 | if (*ctx->cur == '/') |
252 | { | 267 | { |
253 | if (has_host) | 268 | if (has_host) |
@@ -269,7 +284,9 @@ _mu_url_ctx_parse_cred (struct mu_url_ctx *ctx) | |||
269 | int rc, has_cred; | 284 | int rc, has_cred; |
270 | mu_url_t url = ctx->url; | 285 | mu_url_t url = ctx->url; |
271 | const char *save = ctx->cur; | 286 | const char *save = ctx->cur; |
272 | 287 | ||
288 | if (*ctx->cur == 0) | ||
289 | return 0; | ||
273 | rc = getkn (ctx, "@"); | 290 | rc = getkn (ctx, "@"); |
274 | if (rc) | 291 | if (rc) |
275 | return rc; | 292 | return rc; |
@@ -343,12 +360,18 @@ _mu_url_ctx_parse (struct mu_url_ctx *ctx) | |||
343 | { | 360 | { |
344 | int rc; | 361 | int rc; |
345 | mu_url_t url = ctx->url; | 362 | mu_url_t url = ctx->url; |
363 | const char *save = ctx->cur; | ||
346 | 364 | ||
347 | /* Parse the scheme part */ | 365 | /* Parse the scheme part */ |
366 | if (*ctx->cur == ':') | ||
367 | return _mu_url_ctx_parse_cred (ctx); | ||
368 | |||
348 | rc = getkn (ctx, ":/"); | 369 | rc = getkn (ctx, ":/"); |
349 | if (rc) | 370 | if (rc) |
350 | return rc; | 371 | return rc; |
351 | if (*ctx->cur == ':') | 372 | if (*ctx->cur == ':' |
373 | && ((ctx->flags & MU_URL_PARSE_DSLASH_OPTIONAL) | ||
374 | || (ctx->cur[1] == '/' && ctx->cur[2] == '/'))) | ||
352 | { | 375 | { |
353 | rc = str_assign (&url->scheme, ctx->tokbuf); | 376 | rc = str_assign (&url->scheme, ctx->tokbuf); |
354 | if (rc) | 377 | if (rc) |
@@ -356,7 +379,12 @@ _mu_url_ctx_parse (struct mu_url_ctx *ctx) | |||
356 | url->flags |= MU_URL_SCHEME; | 379 | url->flags |= MU_URL_SCHEME; |
357 | ctx->cur++; | 380 | ctx->cur++; |
358 | } | 381 | } |
359 | 382 | else | |
383 | { | ||
384 | ctx->cur = save; | ||
385 | return _mu_url_ctx_parse_cred (ctx); | ||
386 | } | ||
387 | |||
360 | if (*ctx->cur == 0) | 388 | if (*ctx->cur == 0) |
361 | return 0; | 389 | return 0; |
362 | 390 | ||
@@ -535,5 +563,6 @@ mu_url_create (mu_url_t *purl, const char *str) | |||
535 | MU_URL_PARSE_HIDEPASS | | 563 | MU_URL_PARSE_HIDEPASS | |
536 | MU_URL_PARSE_PORTSRV | | 564 | MU_URL_PARSE_PORTSRV | |
537 | MU_URL_PARSE_PIPE | | 565 | MU_URL_PARSE_PIPE | |
538 | MU_URL_PARSE_SLASH, NULL); | 566 | MU_URL_PARSE_SLASH | |
567 | MU_URL_PARSE_DSLASH_OPTIONAL, NULL); | ||
539 | } | 568 | } |