mirror of
https://github.com/aria2/aria2.git
synced 2024-12-02 19:06:32 +00:00
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:
commit
998f203288
@ -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;
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace aria2 {
|
||||
|
||||
namespace bittorrent {
|
||||
|
||||
typedef GenericParser<BencodeParser, ValueBaseStructParserStateMachine>
|
||||
typedef GenericParser<BencodeParser, ValueBaseStructParserStateMachine, true>
|
||||
ValueBaseBencodeParser;
|
||||
|
||||
} // namespace bittorrent
|
||||
|
@ -213,4 +213,9 @@ void ValueBaseStructParserStateMachine::pushNullState()
|
||||
stateStack_.push(nullState);
|
||||
}
|
||||
|
||||
void ValueBaseStructParserStateMachine::setAllowEmptyMemberName(bool b)
|
||||
{
|
||||
ctrl_->setAllowEmptyMemberName(b);
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
@ -106,6 +106,8 @@ public:
|
||||
void pushBoolState();
|
||||
void pushNullState();
|
||||
|
||||
void setAllowEmptyMemberName(bool b);
|
||||
|
||||
private:
|
||||
std::unique_ptr<rpc::XmlRpcRequestParserController> ctrl_;
|
||||
std::stack<ValueBaseStructParserState*> stateStack_;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user