Fixed the bug that DownloadContext::basePath_ is not

escaped. Percent-encode non UTF-8 strings in torrent file and Magnet
URI.
pull/1/head
Tatsuhiro Tsujikawa 2011-02-11 23:46:23 +09:00
parent 7f21099ee7
commit 22a6ec6a15
2 changed files with 28 additions and 26 deletions

View File

@ -622,7 +622,7 @@ void gatherBitTorrentMetadata
const SharedHandle<TorrentAttribute>& torrentAttrs) const SharedHandle<TorrentAttribute>& torrentAttrs)
{ {
if(!torrentAttrs->comment.empty()) { if(!torrentAttrs->comment.empty()) {
btDict->put(KEY_COMMENT, util::encodeNonUtf8(torrentAttrs->comment)); btDict->put(KEY_COMMENT, torrentAttrs->comment);
} }
if(torrentAttrs->creationDate) { if(torrentAttrs->creationDate) {
btDict->put(KEY_CREATION_DATE, Integer::g(torrentAttrs->creationDate)); btDict->put(KEY_CREATION_DATE, Integer::g(torrentAttrs->creationDate));
@ -644,7 +644,7 @@ void gatherBitTorrentMetadata
btDict->put(KEY_ANNOUNCE_LIST, destAnnounceList); btDict->put(KEY_ANNOUNCE_LIST, destAnnounceList);
if(!torrentAttrs->metadata.empty()) { if(!torrentAttrs->metadata.empty()) {
SharedHandle<Dict> infoDict = Dict::g(); SharedHandle<Dict> infoDict = Dict::g();
infoDict->put(KEY_NAME, util::encodeNonUtf8(torrentAttrs->name)); infoDict->put(KEY_NAME, torrentAttrs->name);
btDict->put(KEY_INFO, infoDict); btDict->put(KEY_INFO, infoDict);
} }
} }

View File

@ -144,8 +144,9 @@ void extractUrlList
virtual void visit(const String& v) virtual void visit(const String& v)
{ {
uris_.push_back(v.s()); std::string utf8Uri = util::encodeNonUtf8(v.s());
torrent_->urlList.push_back(v.s()); uris_.push_back(utf8Uri);
torrent_->urlList.push_back(utf8Uri);
} }
virtual void visit(const Integer& v) {} virtual void visit(const Integer& v) {}
@ -156,8 +157,9 @@ void extractUrlList
itr != eoi; ++itr) { itr != eoi; ++itr) {
const String* uri = asString(*itr); const String* uri = asString(*itr);
if(uri) { if(uri) {
uris_.push_back(uri->s()); std::string utf8Uri = util::encodeNonUtf8(uri->s());
torrent_->urlList.push_back(uri->s()); uris_.push_back(utf8Uri);
torrent_->urlList.push_back(utf8Uri);
} }
} }
} }
@ -198,7 +200,6 @@ void extractFileEntries
const std::string& overrideName, const std::string& overrideName,
const std::vector<std::string>& urlList) const std::vector<std::string>& urlList)
{ {
std::string name;
std::string utf8Name; std::string utf8Name;
if(overrideName.empty()) { if(overrideName.empty()) {
std::string nameKey; std::string nameKey;
@ -216,14 +217,13 @@ void extractFileEntries
nameData->s().c_str()), nameData->s().c_str()),
error_code::BITTORRENT_PARSE_ERROR); error_code::BITTORRENT_PARSE_ERROR);
} }
name = nameData->s();
} else { } else {
name = utf8Name = strconcat(File(defaultName).getBasename(), ".file"); utf8Name = strconcat(File(defaultName).getBasename(), ".file");
} }
} else { } else {
name = utf8Name = overrideName; utf8Name = overrideName;
} }
torrent->name = name; torrent->name = utf8Name;
std::vector<SharedHandle<FileEntry> > fileEntries; std::vector<SharedHandle<FileEntry> > fileEntries;
const List* filesList = asList(infoDict->get(C_FILES)); const List* filesList = asList(infoDict->get(C_FILES));
if(filesList) { if(filesList) {
@ -258,7 +258,7 @@ void extractFileEntries
} }
std::vector<std::string> pathelem(pathList->size()+1); std::vector<std::string> pathelem(pathList->size()+1);
pathelem[0] = name; pathelem[0] = utf8Name;
std::vector<std::string>::iterator pathelemOutItr = pathelem.begin(); std::vector<std::string>::iterator pathelemOutItr = pathelem.begin();
++pathelemOutItr; ++pathelemOutItr;
for(List::ValueType::const_iterator itr = pathList->begin(), for(List::ValueType::const_iterator itr = pathList->begin(),
@ -271,7 +271,6 @@ void extractFileEntries
error_code::BITTORRENT_PARSE_ERROR); error_code::BITTORRENT_PARSE_ERROR);
} }
} }
std::string path = strjoin(pathelem.begin(), pathelem.end(), '/');
std::string utf8Path = strjoin(pathelem.begin(), pathelem.end(), '/', std::string utf8Path = strjoin(pathelem.begin(), pathelem.end(), '/',
std::ptr_fun(util::encodeNonUtf8)); std::ptr_fun(util::encodeNonUtf8));
if(util::detectDirTraversal(utf8Path)) { if(util::detectDirTraversal(utf8Path)) {
@ -288,7 +287,7 @@ void extractFileEntries
(new FileEntry(util::applyDir(option->get(PREF_DIR), (new FileEntry(util::applyDir(option->get(PREF_DIR),
util::escapePath(utf8Path)), util::escapePath(utf8Path)),
fileLengthData->i(), offset, uris)); fileLengthData->i(), offset, uris));
fileEntry->setOriginalName(path); fileEntry->setOriginalName(utf8Path);
fileEntries.push_back(fileEntry); fileEntries.push_back(fileEntry);
offset += fileEntry->getLength(); offset += fileEntry->getLength();
} }
@ -308,7 +307,7 @@ void extractFileEntries
for(std::vector<std::string>::const_iterator i = urlList.begin(), for(std::vector<std::string>::const_iterator i = urlList.begin(),
eoi = urlList.end(); i != eoi; ++i) { eoi = urlList.end(); i != eoi; ++i) {
if(util::endsWith(*i, A2STR::SLASH_C)) { if(util::endsWith(*i, A2STR::SLASH_C)) {
uris.push_back((*i)+util::percentEncode(name)); uris.push_back((*i)+util::percentEncode(utf8Name));
} else { } else {
uris.push_back(*i); uris.push_back(*i);
} }
@ -317,12 +316,13 @@ void extractFileEntries
(new FileEntry(util::applyDir(option->get(PREF_DIR), (new FileEntry(util::applyDir(option->get(PREF_DIR),
util::escapePath(utf8Name)), util::escapePath(utf8Name)),
totalLength, 0, uris)); totalLength, 0, uris));
fileEntry->setOriginalName(name); fileEntry->setOriginalName(utf8Name);
fileEntries.push_back(fileEntry); fileEntries.push_back(fileEntry);
} }
ctx->setFileEntries(fileEntries.begin(), fileEntries.end()); ctx->setFileEntries(fileEntries.begin(), fileEntries.end());
if(torrent->mode == MULTI) { if(torrent->mode == MULTI) {
ctx->setBasePath(util::applyDir(option->get(PREF_DIR), utf8Name)); ctx->setBasePath(util::applyDir(option->get(PREF_DIR),
util::escapePath(utf8Name)));
} }
} }
} // namespace } // namespace
@ -344,7 +344,7 @@ void extractAnnounce
eoi2 = tier->end(); uriIter != eoi2; ++uriIter) { eoi2 = tier->end(); uriIter != eoi2; ++uriIter) {
const String* uri = asString(*uriIter); const String* uri = asString(*uriIter);
if(uri) { if(uri) {
ntier.push_back(util::strip(uri->s())); ntier.push_back(util::encodeNonUtf8(util::strip(uri->s())));
} }
} }
if(!ntier.empty()) { if(!ntier.empty()) {
@ -355,7 +355,7 @@ void extractAnnounce
const String* announce = asString(rootDict->get(C_ANNOUNCE)); const String* announce = asString(rootDict->get(C_ANNOUNCE));
if(announce) { if(announce) {
std::vector<std::string> tier; std::vector<std::string> tier;
tier.push_back(util::strip(announce->s())); tier.push_back(util::encodeNonUtf8(util::strip(announce->s())));
torrent->announceList.push_back(tier); torrent->announceList.push_back(tier);
} }
} }
@ -378,14 +378,16 @@ void extractNodes
if(!hostname) { if(!hostname) {
continue; continue;
} }
if(util::strip(hostname->s()).empty()) { std::string utf8Hostname =
util::encodeNonUtf8(util::strip(hostname->s()));
if(utf8Hostname.empty()) {
continue; continue;
} }
const Integer* port = asInteger(addrPairList->get(1)); const Integer* port = asInteger(addrPairList->get(1));
if(!port || !(0 < port->i() && port->i() < 65536)) { if(!port || !(0 < port->i() && port->i() < 65536)) {
continue; continue;
} }
torrent->nodes.push_back(std::make_pair(hostname->s(), port->i())); torrent->nodes.push_back(std::make_pair(utf8Hostname, port->i()));
} }
} }
} }
@ -486,16 +488,16 @@ void processRootDictionary
} }
const String* commentUtf8 = asString(rootDict->get(C_COMMENT_UTF8)); const String* commentUtf8 = asString(rootDict->get(C_COMMENT_UTF8));
if(commentUtf8) { if(commentUtf8) {
torrent->comment = commentUtf8->s(); torrent->comment = util::encodeNonUtf8(commentUtf8->s());
} else { } else {
const String* comment = asString(rootDict->get(C_COMMENT)); const String* comment = asString(rootDict->get(C_COMMENT));
if(comment) { if(comment) {
torrent->comment = comment->s(); torrent->comment = util::encodeNonUtf8(comment->s());
} }
} }
const String* createdBy = asString(rootDict->get(C_CREATED_BY)); const String* createdBy = asString(rootDict->get(C_CREATED_BY));
if(createdBy) { if(createdBy) {
torrent->createdBy = createdBy->s(); torrent->createdBy = util::encodeNonUtf8(createdBy->s());
} }
ctx->setAttribute(BITTORRENT, torrent); ctx->setAttribute(BITTORRENT, torrent);
@ -975,7 +977,7 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
for(List::ValueType::const_iterator i = trs->begin(), eoi = trs->end(); for(List::ValueType::const_iterator i = trs->begin(), eoi = trs->end();
i != eoi; ++i) { i != eoi; ++i) {
std::vector<std::string> tier; std::vector<std::string> tier;
tier.push_back(asString(*i)->s()); tier.push_back(util::encodeNonUtf8(asString(*i)->s()));
attrs->announceList.push_back(tier); attrs->announceList.push_back(tier);
} }
} }
@ -983,7 +985,7 @@ SharedHandle<TorrentAttribute> parseMagnet(const std::string& magnet)
const List* dns = asList(r->get("dn")); const List* dns = asList(r->get("dn"));
if(dns && !dns->empty()) { if(dns && !dns->empty()) {
const String* dn = asString(dns->get(0)); const String* dn = asString(dns->get(0));
name += dn->s(); name += util::encodeNonUtf8(dn->s());
} else { } else {
name += util::toHex(infoHash); name += util::toHex(infoHash);
} }