Merge pull request #1905 from aria2/bt-bencode-allow-empty-dict-name

Allow empty dist name in bencode which is needed for hybrid torrent
This commit is contained in:
Tatsuhiro Tsujikawa 2022-04-08 23:29:13 +09:00 committed by GitHub
commit 998f203288
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 5 deletions

View File

@ -42,9 +42,14 @@
namespace aria2 {
template <typename Parser, typename ParserStateMachine> class GenericParser {
template <typename Parser, typename ParserStateMachine,
bool allowEmptyName = false>
class GenericParser {
public:
GenericParser() : parser_{&psm_} {}
GenericParser() : parser_{&psm_}
{
psm_.setAllowEmptyMemberName(allowEmptyName);
}
~GenericParser() = default;

View File

@ -43,7 +43,7 @@ namespace aria2 {
namespace bittorrent {
typedef GenericParser<BencodeParser, ValueBaseStructParserStateMachine>
typedef GenericParser<BencodeParser, ValueBaseStructParserStateMachine, true>
ValueBaseBencodeParser;
} // namespace bittorrent

View File

@ -213,4 +213,9 @@ void ValueBaseStructParserStateMachine::pushNullState()
stateStack_.push(nullState);
}
void ValueBaseStructParserStateMachine::setAllowEmptyMemberName(bool b)
{
ctrl_->setAllowEmptyMemberName(b);
}
} // namespace aria2

View File

@ -106,6 +106,8 @@ public:
void pushBoolState();
void pushNullState();
void setAllowEmptyMemberName(bool b);
private:
std::unique_ptr<rpc::XmlRpcRequestParserController> ctrl_;
std::stack<ValueBaseStructParserState*> stateStack_;

View File

@ -54,7 +54,7 @@ void XmlRpcRequestParserController::popStructFrame()
Dict* dict = downcast<Dict>(parentFrame.value_);
assert(dict);
frameStack_.pop();
if (currentFrame_.validMember()) {
if (currentFrame_.validMember(allowEmptyMemberName_)) {
dict->put(std::move(currentFrame_.name_), std::move(currentFrame_.value_));
}
currentFrame_ = std::move(parentFrame);
@ -110,6 +110,11 @@ void XmlRpcRequestParserController::setMethodName(std::string methodName)
methodName_ = std::move(methodName);
}
void XmlRpcRequestParserController::setAllowEmptyMemberName(bool b)
{
allowEmptyMemberName_ = b;
}
} // namespace rpc
} // namespace aria2

View File

@ -52,7 +52,10 @@ private:
std::unique_ptr<ValueBase> value_;
std::string name_;
bool validMember() const { return value_ && !name_.empty(); }
bool validMember(bool allowEmptyMemberName) const
{
return value_ && (allowEmptyMemberName || !name_.empty());
}
void reset()
{
@ -67,7 +70,11 @@ private:
std::string methodName_;
bool allowEmptyMemberName_;
public:
XmlRpcRequestParserController() : allowEmptyMemberName_(false) {}
void pushFrame();
// Pops StateFrame p from frameStack_ and set p[currentFrame_.name_]
@ -90,6 +97,8 @@ public:
const std::string& getMethodName() const { return methodName_; }
void setAllowEmptyMemberName(bool b);
void reset();
};

View File

@ -208,6 +208,16 @@ void ValueBaseBencodeParserTest::testParseUpdate()
// Get trailing garbage position
CPPUNIT_ASSERT_EQUAL((ssize_t)7, error);
}
{
// dict, empty member name
std::string src = "d0:i123ee";
std::shared_ptr<ValueBase> d =
parser.parseFinal(src.c_str(), src.size(), error);
Dict* dict = downcast<Dict>(d);
CPPUNIT_ASSERT(dict);
CPPUNIT_ASSERT(dict->get(""));
CPPUNIT_ASSERT_EQUAL((int64_t)123, downcast<Integer>(dict->get(""))->i());
}
}
} // namespace aria2