From 67297ae805d42af60fbcce4f804353259e3d8015 Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Mon, 31 Mar 2014 21:37:54 +0200 Subject: [PATCH 1/2] Fix metalink issues when type is not present --- src/ChangeLog | 14 ++++++++++++++ src/metalink.c | 23 ++++++++++++++++------- src/metalink.h | 4 +++- src/retr.c | 10 ++++++++++ src/url.c | 22 ++++++++++++++++++++++ src/url.h | 1 + 6 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 537a707..74d061e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2014-03-31 Jure Grabnar + + * metalink.h: Change type of 'mlink_resource.type' to enum url_scheme. + Include url.h. + * metalink.c (parse_metalink): Find out resources' protocol type from URL if + not present in tag in metalink file. + Include url.h. + (elect_resources): Do not crash when protocol type is NULL. + Count number of resources still available, if zero, assign NULL. + * url.c: + (url_scheme_str_to_enum): New function: extracts protocol type from string + without "://" suffix. + * retr.c: Add check for number of resources available. Do not crash when zero. + 2014-03-26 Darshit Shah * ftp.c (getftp): Rearrange parameters to fix compiler warning diff --git a/src/metalink.c b/src/metalink.c index 76db2fa..4ff565d 100644 --- a/src/metalink.c +++ b/src/metalink.c @@ -42,6 +42,7 @@ as that of the covered work. */ #include "sha256.h" #include "metalink.h" #include "utils.h" +#include "url.h" #define HASH_TYPES 3 @@ -119,7 +120,7 @@ parse_metalink(char *input_file) file->chunk_checksum = NULL; file->num_of_res = file->num_of_checksums = 0; - for (resources = (*files)->resources; *resources; ++resources) + for (resources = (*files)->resources; resources && *resources; ++resources) { mlink_resource *resource; @@ -134,7 +135,12 @@ parse_metalink(char *input_file) ++(file->num_of_res); resource->url = xstrdup ((*resources)->url); - resource->type = ((*resources)->type ? xstrdup ((*resources)->type) : NULL); + + if ((*resources)->type) + resource->type = url_scheme_str_to_enum ((*resources)->type); + else + resource->type = url_scheme (resource->url); + resource->location = ((*resources)->location ? xstrdup ((*resources)->location) : NULL); resource->preference = (*resources)->preference; resource->maxconnections = (*resources)->maxconnections; @@ -143,7 +149,7 @@ parse_metalink(char *input_file) (file->resources) = resource; } - for (checksums = (*files)->checksums; *checksums; ++checksums) + for (checksums = (*files)->checksums; checksums && *checksums; ++checksums) { mlink_checksum *checksum = malloc (sizeof(mlink_checksum)); @@ -215,19 +221,23 @@ elect_resources (mlink *mlink) while (res_next = res->next) { - if (strcmp(res_next->type, "ftp") && strcmp(res_next->type, "http")) + if (schemes_are_similar_p (res_next->type, SCHEME_INVALID)) { res->next = res_next->next; free(res_next); + + --(file->num_of_res); } else res = res_next; } res = file->resources; - if (strcmp(res->type, "ftp") && strcmp(res->type, "http")) + if (schemes_are_similar_p (res->type, SCHEME_INVALID)) { file->resources = res->next; - free(res); + free (res); + + --(file->num_of_res); } } } @@ -301,7 +311,6 @@ delete_mlink(mlink *metalink) while (res) { xfree_null (res->url); - xfree_null (res->type); xfree_null (res->location); res_temp = res; diff --git a/src/metalink.h b/src/metalink.h index 3906e22..264320c 100644 --- a/src/metalink.h +++ b/src/metalink.h @@ -32,6 +32,8 @@ as that of the covered work. */ #ifndef MLINK_H #define MLINK_H +#include "url.h" + typedef struct metalink_piece_hash { struct metalink_piece_hash *next; @@ -53,7 +55,7 @@ typedef struct metalink_resource struct metalink_resource *next; char *url; - char *type; + enum url_scheme type; char *location; int preference; int maxconnections; diff --git a/src/retr.c b/src/retr.c index 8c361de..d89fc83 100644 --- a/src/retr.c +++ b/src/retr.c @@ -1095,6 +1095,16 @@ retrieve_from_file (const char *file, bool html, int *count) file = mlink->files; while (file) { + if (!file->num_of_res) + { + logprintf (LOG_VERBOSE, _("Downloading %s failed. File could " + "not be downloaded from any of the " + "URLs listed in metalink file.\n"), + file->name); + file = file->next; + continue; + } + memset (thread_ctx, '\0', opt.jobs * (sizeof *thread_ctx)); /* If chunk_size is too small, set it equal to MIN_CHUNK_SIZE. */ diff --git a/src/url.c b/src/url.c index a237fcf..95babfd 100644 --- a/src/url.c +++ b/src/url.c @@ -440,6 +440,28 @@ url_scheme (const char *url) return SCHEME_INVALID; } +/* Returns the scheme type from string + if the scheme is supported, or + SCHEME_INVALID if not. */ + +enum url_scheme +url_scheme_str_to_enum (const char *str) +{ + int i; + + for (i = 0; supported_schemes[i].name; i++) + if (0 == strncasecmp (str, supported_schemes[i].name, + strlen (supported_schemes[i].name))) + { + if (!(supported_schemes[i].flags & scm_disabled)) + return (enum url_scheme) i; + else + return SCHEME_INVALID; + } + + return SCHEME_INVALID; +} + #define SCHEME_CHAR(ch) (c_isalnum (ch) || (ch) == '-' || (ch) == '+') /* Return 1 if the URL begins with any "scheme", 0 otherwise. As diff --git a/src/url.h b/src/url.h index 6d18ed8..cb26ef4 100644 --- a/src/url.h +++ b/src/url.h @@ -111,6 +111,7 @@ void url_set_file (struct url *, const char *); void url_free (struct url *); enum url_scheme url_scheme (const char *); +enum url_scheme url_scheme_str_to_enum (const char *str); bool url_has_scheme (const char *); bool url_valid_scheme (const char *); int scheme_default_port (enum url_scheme); -- 1.9.0