| author | Rink Springer <rink@rink.nu> |
| Sun Jul 31 12:34:24 2011 +0200 (6 months ago ago) | |
| changeset 328 | 89367a44e2dc |
| parent 327 | b023a55427b4 |
When parsing trackers, revert to the old-style 'announce' URL if 'announce-list' is corrupt
I've seen one torrent which has an empty 'announce-list', causing it to be rejected completely. This may be overly strict, even though the presence of of an empty 'announce-list' should be considered a bug.
I've seen one torrent which has an empty 'announce-list', causing it to be rejected completely. This may be overly strict, even though the presence of of an empty 'announce-list' should be considered a bug.
1.1 --- a/lib/trackertalker.cc Sun Jul 31 12:12:56 2011 +0200 1.2 +++ b/lib/trackertalker.cc Sun Jul 31 12:34:24 2011 +0200 1.3 @@ -70,31 +70,46 @@ 1.4 torrent = t; httpRequest = NULL; 1.5 1.6 const MetaList* mlList = dynamic_cast<const MetaList*>((*dictionary)["announce-list"]); 1.7 - if (mlList == NULL) { 1.8 - /* New-style announce list unavailable; revert to old single URL */ 1.9 - const MetaString* msAnnounce = dynamic_cast<const MetaString*>((*dictionary)["announce"]); 1.10 - if (msAnnounce == NULL) 1.11 - throw TrackerException("metadata doesn't contain an announce URL or list"); 1.12 + if (mlList != NULL) { 1.13 + /* 1.14 + * An announce-list is made up of lists of sublists. Each sublist is an 1.15 + * announcement tier, and contains a list of strings which must be shuffeled 1.16 + * and stored. Each of the tiers must be tried in-order. 1.17 + */ 1.18 + try { 1.19 + for (list<MetaField*>::const_iterator it = mlList->getList().begin(); 1.20 + it != mlList->getList().end(); it++) { 1.21 + MetaList* tierList = dynamic_cast<MetaList*>(*it); 1.22 + if (tierList == NULL) 1.23 + throw TorrentException("announce list doesn't contain a list element"); 1.24 1.25 - string url = msAnnounce->getString(); 1.26 - TRACE(TRACKER, "added old-style tracker: %s", url.c_str()); 1.27 - tiers.push_back(new AnnounceTier(this, url)); 1.28 - return; 1.29 + tiers.push_back(new AnnounceTier(this, tierList)); 1.30 + } 1.31 + } catch (TortillaException) { 1.32 + /* 1.33 + * Something went wrong while adding tiers; throw them all away and 1.34 + * attempt to add the old-style single URL. 1.35 + */ 1.36 + for (vector<AnnounceTier*>::iterator it = tiers.begin(); 1.37 + it != tiers.end(); it++) { 1.38 + delete (*it); 1.39 + } 1.40 + tiers.clear(); 1.41 + } 1.42 } 1.43 1.44 - /* 1.45 - * An announce-list is made up of lists of sublists. Each sublist is an 1.46 - * announcement tier, and contains a list of strings which must be shuffeled 1.47 - * and stored. Each of the tiers must be tried in-order. 1.48 - */ 1.49 - for (list<MetaField*>::const_iterator it = mlList->getList().begin(); 1.50 - it != mlList->getList().end(); it++) { 1.51 - MetaList* tierList = dynamic_cast<MetaList*>(*it); 1.52 - if (tierList == NULL) 1.53 - throw TorrentException("announce list doesn't contain a list element"); 1.54 + /* If we have an announce list, we're good to go */ 1.55 + if (!tiers.empty()) 1.56 + return; 1.57 1.58 - tiers.push_back(new AnnounceTier(this, tierList)); 1.59 - } 1.60 + /* New-style announce list unavailable or corrupt; revert to old single URL */ 1.61 + const MetaString* msAnnounce = dynamic_cast<const MetaString*>((*dictionary)["announce"]); 1.62 + if (msAnnounce == NULL) 1.63 + throw TrackerException("metadata doesn't contain an announce URL or list"); 1.64 + 1.65 + string url = msAnnounce->getString(); 1.66 + TRACE(TRACKER, "added old-style tracker: %s", url.c_str()); 1.67 + tiers.push_back(new AnnounceTier(this, url)); 1.68 } 1.69 1.70 TrackerTalker::~TrackerTalker()