Esempio n. 1
0
		void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth)
		{
			if (depth >= 100)
			{
				err = true;
				return;
			}

			if (in == end)
			{
				err = true;
#ifdef TORRENT_DEBUG
				ret.m_type_queried = false;
#endif
				return;
			}
			switch (*in)
			{

			// ----------------------------------------------
			// integer
			case 'i':
				{
				++in; // 'i'
				std::string val = read_until(in, end, 'e', err);
				if (err) return;
				TORRENT_ASSERT(*in == 'e');
				++in; // 'e'
				ret = entry(entry::int_t);
				char* end_pointer;
				ret.integer() = strtoll(val.c_str(), &end_pointer, 10);
#ifdef TORRENT_DEBUG
				ret.m_type_queried = false;
#endif
				if (end_pointer == val.c_str())
				{
					err = true;
					return;
				}
				} break;

			// ----------------------------------------------
			// list
			case 'l':
				{
				ret = entry(entry::list_t);
				++in; // 'l'
				while (*in != 'e')
				{
					ret.list().push_back(entry());
					entry& e = ret.list().back();
					bdecode_recursive(in, end, e, err, depth + 1);
					if (err)
					{
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
					if (in == end)
					{
						err = true;
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
				}
#ifdef TORRENT_DEBUG
				ret.m_type_queried = false;
#endif
				TORRENT_ASSERT(*in == 'e');
				++in; // 'e'
				} break;

			// ----------------------------------------------
			// dictionary
			case 'd':
				{
				ret = entry(entry::dictionary_t);
				++in; // 'd'
				while (*in != 'e')
				{
					entry key;
					bdecode_recursive(in, end, key, err, depth + 1);
					if (err || key.type() != entry::string_t)
					{
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
					entry& e = ret[key.string()];
					bdecode_recursive(in, end, e, err, depth + 1);
					if (err)
					{
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
					if (in == end)
					{
						err = true;
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
				}
#ifdef TORRENT_DEBUG
				ret.m_type_queried = false;
#endif
				TORRENT_ASSERT(*in == 'e');
				++in; // 'e'
				} break;

			// ----------------------------------------------
			// string
			default:
				if (is_digit(boost::uint8_t(*in)))
				{
					std::string len_s = read_until(in, end, ':', err);
					if (err)
					{
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
					TORRENT_ASSERT(*in == ':');
					++in; // ':'
					int len = atoi(len_s.c_str());
					ret = entry(entry::string_t);
					read_string(in, end, len, ret.string(), err);
					if (err)
					{
#ifdef TORRENT_DEBUG
						ret.m_type_queried = false;
#endif
						return;
					}
				}
				else
				{
					err = true;
#ifdef TORRENT_DEBUG
					ret.m_type_queried = false;
#endif
					return;
				}
#ifdef TORRENT_DEBUG
				ret.m_type_queried = false;
#endif
			}
		}
Esempio n. 2
0
	void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth)
	{
		if (depth >= 100)
		{
			err = true;
			return;
		}

		if (in == end)
		{
			err = true;
			return;
		}
		switch (*in)
		{

		// ----------------------------------------------
		// integer
		case 'i':
			{
			++in; // 'i' 
			std::string val = read_until(in, end, 'e', err);
			if (err) return;
			BOOST_ASSERT(*in == 'e');
			++in; // 'e' 
			ret = entry(entry::int_t);
			char* end_pointer;
#if defined WIN32 && !defined _MINGW
			ret.integer() = _strtoi64(val.c_str(), &end_pointer, 10);
#else
			ret.integer() = strtoll(val.c_str(), &end_pointer, 10);
#endif
			if (end_pointer == val.c_str())
			{
				err = true;
				return;
			}
			} break;

		// ----------------------------------------------
		// list
		case 'l':
			{
			ret = entry(entry::list_t);
			++in; // 'l'
			while (*in != 'e')
			{
				ret.list().push_back(entry());
				entry& e = ret.list().back();
				bdecode_recursive(in, end, e, err, depth + 1);
				if (err)
				{
					return;
				}
				if (in == end)
				{
					err = true;
					return;
				}
			}
			BOOST_ASSERT(*in == 'e');
			++in; // 'e'
			} break;

		// ----------------------------------------------
		// dictionary
		case 'd':
			{
			ret = entry(entry::dictionary_t);
			++in; // 'd'
			while (*in != 'e')
			{
				entry key;
				bdecode_recursive(in, end, key, err, depth + 1);
				if (err || key.type() != entry::string_t)
				{
					return;
				}
				entry& e = ret[key.string()];
				bdecode_recursive(in, end, e, err, depth + 1);
				if (err)
				{
					return;
				}
				if (in == end)
				{
					err = true;
					return;
				}
			}
			BOOST_ASSERT(*in == 'e');
			++in; // 'e'
			} break;

		// ----------------------------------------------
		// string
		default:
			if (is_digit((unsigned char)*in))
			{
				std::string len_s = read_until(in, end, ':', err);
				if (err)
				{
					return;
				}
				BOOST_ASSERT(*in == ':');
				++in; // ':'
				int len = std::atoi(len_s.c_str());
				ret = entry(entry::string_t);
				read_string(in, end, len, ret.string(), err);
				if (err)
				{
					return;
				}
			}
			else
			{
				err = true;
				return;
			}
		}
	}
Esempio n. 3
0
		void bdecode_recursive(InIt& in, InIt end, entry& ret)
		{
			if (in == end) throw invalid_encoding();
			switch (*in)
			{

			// ----------------------------------------------
			// integer
			case 'i':
				{
				++in; // 'i' 
				std::string val = read_until(in, end, 'e');
				assert(*in == 'e');
				++in; // 'e' 
				ret = entry(entry::int_t);
				ret.integer() = boost::lexical_cast<entry::integer_type>(val);
				} break;

			// ----------------------------------------------
			// list
			case 'l':
				{
				ret = entry(entry::list_t);
				++in; // 'l'
				while (*in != 'e')
				{
					ret.list().push_back(entry());
					entry& e = ret.list().back();
					bdecode_recursive(in, end, e);
					if (in == end) throw invalid_encoding();
				}
				assert(*in == 'e');
				++in; // 'e'
				} break;

			// ----------------------------------------------
			// dictionary
			case 'd':
				{
				ret = entry(entry::dictionary_t);
				++in; // 'd'
				while (*in != 'e')
				{
					entry key;
					bdecode_recursive(in, end, key);
					entry& e = ret[key.string()];
					bdecode_recursive(in, end, e);
					if (in == end) throw invalid_encoding();
				}
				assert(*in == 'e');
				++in; // 'e'
				} break;

			// ----------------------------------------------
			// string
			default:
				if (isdigit(*in))
				{
					std::string len_s = read_until(in, end, ':');
					assert(*in == ':');
					++in; // ':'
					int len = std::atoi(len_s.c_str());
					ret = entry(entry::string_t);
					ret.string() = read_string(in, end, len);
				}
				else
				{
					throw invalid_encoding();
				}
			}
		}
Esempio n. 4
0
		void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth)
		{
			if (depth >= 100)
			{
				err = true;
				return;
			}

			if (in == end)
			{
				err = true;
				return;
			}
			switch (*in)
			{

			// ----------------------------------------------
			// integer
			case 'i':
				{
				++in; // 'i' 
				std::string val = read_until(in, end, 'e', err);
				if (err) return;
				TORRENT_ASSERT(*in == 'e');
				++in; // 'e' 
				ret = entry(entry::int_t);
				ret.integer() = boost::lexical_cast<entry::integer_type>(val);
				} break;

			// ----------------------------------------------
			// list
			case 'l':
				{
				ret = entry(entry::list_t);
				++in; // 'l'
				while (*in != 'e')
				{
					ret.list().push_back(entry());
					entry& e = ret.list().back();
					bdecode_recursive(in, end, e, err, depth + 1);
					if (err) return;
					if (in == end)
					{
						err = true;
						return;
					}
				}
				TORRENT_ASSERT(*in == 'e');
				++in; // 'e'
				} break;

			// ----------------------------------------------
			// dictionary
			case 'd':
				{
				ret = entry(entry::dictionary_t);
				++in; // 'd'
				while (*in != 'e')
				{
					entry key;
					bdecode_recursive(in, end, key, err, depth + 1);
					if (err) return;
					entry& e = ret[key.string()];
					bdecode_recursive(in, end, e, err, depth + 1);
					if (err) return;
					if (in == end)
					{
						err = true;
						return;
					}
				}
				TORRENT_ASSERT(*in == 'e');
				++in; // 'e'
				} break;

			// ----------------------------------------------
			// string
			default:
				if (isdigit((unsigned char)*in))
				{
					std::string len_s = read_until(in, end, ':', err);
					if (err) return;
					TORRENT_ASSERT(*in == ':');
					++in; // ':'
					int len = std::atoi(len_s.c_str());
					ret = entry(entry::string_t);
					read_string(in, end, len, ret.string(), err);
					if (err) return;
				}
				else
				{
					err = true;
					return;
				}
			}
		}