diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2016-03-17 23:28:28 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2016-03-17 23:28:28 +0900 |
| commit | f316c947100f7683f4ca9ba1c71bb1446433dbb4 (patch) | |
| tree | 185ac72d1440f26570b52ba0fb4942deb792b545 | |
| parent | 9b607bbae0b397fffc53339aae36e9f8547cfd12 (diff) | |
Ignore floating number in torrent file
| -rw-r--r-- | src/BencodeParser.cc | 40 | ||||
| -rw-r--r-- | src/BencodeParser.h | 3 | ||||
| -rw-r--r-- | test/ValueBaseBencodeParserTest.cc | 12 |
3 files changed, 52 insertions, 3 deletions
diff --git a/src/BencodeParser.cc b/src/BencodeParser.cc index f5423072..08d36b21 100644 --- a/src/BencodeParser.cc +++ b/src/BencodeParser.cc @@ -55,7 +55,8 @@ enum { BENCODE_STRING_LEN, BENCODE_STRING, BENCODE_NUMBER_SIGN, - BENCODE_NUMBER + BENCODE_NUMBER, + BENCODE_FLOAT_NUMBER_IGNORE, }; } // namespace @@ -216,11 +217,32 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size) } numConsumed_ += j - i; if (j != size) { - if (data[j] != 'e' || numConsumed_ == 0) { + if (numConsumed_ == 0) { currentState_ = BENCODE_ERROR; return lastError_ = ERR_INVALID_NUMBER; } + + auto c = data[j]; + if (util::isDigit(c) || c == '.' || c == 'E' || c == '+' || c == '-') { + // some torrent generator adds floating point number in + // scientific notation (e.g., -1.134E+3) in integer field. + // In this case, just skip these bytes until we find 'e'. + number_ = 0; + numConsumed_ = 0; + currentState_ = BENCODE_FLOAT_NUMBER_IGNORE; + + i = j; + + break; + } + + if (c != 'e') { + currentState_ = BENCODE_ERROR; + return lastError_ = ERR_INVALID_NUMBER; + } + i = j; + onNumberEnd(); } else { @@ -228,6 +250,20 @@ ssize_t BencodeParser::parseUpdate(const char* data, size_t size) } break; } + case BENCODE_FLOAT_NUMBER_IGNORE: { + auto c = data[i]; + if (util::isDigit(c) || c == '.' || c == 'E' || c == '+' || c == '-') { + continue; + } + + if (c != 'e') { + currentState_ = BENCODE_ERROR; + return lastError_ = ERR_INVALID_FLOAT_NUMBER; + } + + onNumberEnd(); + break; + } } } return i; diff --git a/src/BencodeParser.h b/src/BencodeParser.h index c6b7debd..7ef697c1 100644 --- a/src/BencodeParser.h +++ b/src/BencodeParser.h @@ -52,7 +52,8 @@ enum BencodeError { ERR_PREMATURE_DATA = -4, ERR_STRUCTURE_TOO_DEEP = -5, ERR_INVALID_STRING_LENGTH = -6, - ERR_STRING_LENGTH_OUT_OF_RANGE = -7 + ERR_STRING_LENGTH_OUT_OF_RANGE = -7, + ERR_INVALID_FLOAT_NUMBER = -8, }; class BencodeParser { diff --git a/test/ValueBaseBencodeParserTest.cc b/test/ValueBaseBencodeParserTest.cc index a24af6d3..30cca2f4 100644 --- a/test/ValueBaseBencodeParserTest.cc +++ b/test/ValueBaseBencodeParserTest.cc @@ -3,6 +3,7 @@ #include <cppunit/extensions/HelperMacros.h> #include "ValueBase.h" +#include "BencodeParser.h" namespace aria2 { @@ -78,6 +79,12 @@ void ValueBaseBencodeParserTest::testParseUpdate() downcast<Integer>(s)->i()); } { + // float number, ignored and always 0. + std::string src = "i+343243.342E-1333e"; + auto s = parser.parseFinal(src.c_str(), src.size(), error); + CPPUNIT_ASSERT_EQUAL((int64_t)0, downcast<Integer>(s)->i()); + } + { // dict, size 1 std::string src = "d3:fooi123ee"; std::shared_ptr<ValueBase> d = @@ -187,6 +194,11 @@ void ValueBaseBencodeParserTest::testParseUpdate() checkDecodeError(std::string(51, 'l') + std::string(51, 'e')); checkDecodeError(std::string(50, 'l') + "d3:fooi100ee" + std::string(50, 'e')); + // float number, but including bad characters + checkDecodeError("i-1.134a+33e"); + checkDecodeError("ixe"); + // empty number + checkDecodeError("ie"); { // ignore trailing garbage at the end of the input. std::string src = "5:aria2trail"; |
