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