mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-08 07:09:21 +00:00
Compare commits
3 Commits
7916e6022f
...
v0.16.24
| Author | SHA1 | Date | |
|---|---|---|---|
| 05cdd03cd2 | |||
| d1a6942ea7 | |||
| 3652329e2d |
+3
-3
@@ -1,6 +1,6 @@
|
||||
m4_pattern_allow([PKG_CHECK_EXISTS])
|
||||
|
||||
AC_INIT([rtorrent],[0.16.23],[sundell.software@gmail.com])
|
||||
AC_INIT([rtorrent],[0.16.24],[sundell.software@gmail.com])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIRS([scripts])
|
||||
@@ -14,7 +14,7 @@ AX_CXX_COMPILE_STDCXX(20, noext, mandatory)
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_DEFINE([API_VERSION], [27], [api version])
|
||||
AC_DEFINE([API_VERSION], [28], [api version])
|
||||
|
||||
RAK_CHECK_CFLAGS
|
||||
RAK_CHECK_CXXFLAGS
|
||||
@@ -49,7 +49,7 @@ fi
|
||||
|
||||
PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
|
||||
PKG_CHECK_MODULES([ZLIB], [zlib])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.23])
|
||||
PKG_CHECK_MODULES([DEPENDENCIES], [libtorrent >= 0.16.24])
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
TORRENT_WITH_XMLRPC_C
|
||||
|
||||
@@ -26,10 +26,7 @@ const size_t object_storage::key_size;
|
||||
|
||||
object_storage::iterator
|
||||
object_storage::find_raw_string(const torrent::raw_string& key) {
|
||||
fixed_key_type<64> k;
|
||||
k.set_c_str(key.data());
|
||||
|
||||
return find(k);
|
||||
return find(key_type::from_raw_string(key));
|
||||
}
|
||||
|
||||
object_storage::iterator
|
||||
|
||||
@@ -158,14 +158,7 @@ fixed_key_type<MaxSize>::set_data(const value_type* src_data, size_type src_size
|
||||
|
||||
template <size_t MaxSize> inline void
|
||||
fixed_key_type<MaxSize>::set_c_str(const value_type* src_data) {
|
||||
value_type* itr = m_data;
|
||||
const value_type* last = m_data + max_size;
|
||||
|
||||
while (itr != last && *src_data != '\0')
|
||||
*itr++ = *src_data++;
|
||||
|
||||
*itr = '\0';
|
||||
m_size = std::distance(m_data, itr);
|
||||
set_c_str(src_data, std::strlen(src_data));
|
||||
}
|
||||
|
||||
template <size_t MaxSize> inline void
|
||||
|
||||
+36
-8
@@ -30,6 +30,38 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
std::string
|
||||
create_filter_pattern(const std::string& input) {
|
||||
std::string pattern = input;
|
||||
|
||||
if (pattern.empty())
|
||||
return pattern;
|
||||
|
||||
if (pattern.back() != '$')
|
||||
pattern = pattern + ".*";
|
||||
if (pattern.front() != '^')
|
||||
pattern = ".*" + pattern;
|
||||
|
||||
std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
|
||||
return pattern;
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
create_filter_command(const std::string& pattern) {
|
||||
torrent::Object name = torrent::Object::create_dict_key();
|
||||
name.as_dict_key() = "d.name";
|
||||
|
||||
torrent::Object args = torrent::Object::create_list();
|
||||
args.as_list().push_back(name);
|
||||
args.as_list().push_back(torrent::Object(pattern));
|
||||
|
||||
torrent::Object command = torrent::Object::create_dict_key();
|
||||
command.as_dict_key() = "match";
|
||||
command.as_dict_obj() = args;
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
DownloadList::DownloadList() {
|
||||
m_uiArray[DISPLAY_DOWNLOAD] = NULL;
|
||||
m_uiArray[DISPLAY_DOWNLOAD_LIST] = new ElementDownloadList();
|
||||
@@ -319,16 +351,12 @@ DownloadList::receive_exit_input(Input type) {
|
||||
current_view()->filter();
|
||||
current_view()->sort();
|
||||
} else {
|
||||
std::string pattern = input->str();
|
||||
if (pattern.back() != '$')
|
||||
pattern = pattern + ".*";
|
||||
if (pattern.front() != '^')
|
||||
pattern = ".*" + pattern;
|
||||
std::transform(pattern.begin(), pattern.end(), pattern.begin(), ::tolower);
|
||||
std::string temp_filter = "match={d.name=," + pattern + "}";
|
||||
std::string pattern = create_filter_pattern(input->str());
|
||||
|
||||
if (rpc::call_command_value("view.filter.temp.log"))
|
||||
control->core()->push_log_std("Temporary filter on '" + current_view()->name() + "' view: " + pattern);
|
||||
current_view()->set_filter_temp(temp_filter);
|
||||
|
||||
current_view()->set_filter_temp(create_filter_command(pattern));
|
||||
current_view()->filter();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef RTORRENT_UI_DOWNLOAD_LIST_H
|
||||
#define RTORRENT_UI_DOWNLOAD_LIST_H
|
||||
|
||||
#include <string>
|
||||
#include <torrent/object.h>
|
||||
|
||||
#include "element_base.h"
|
||||
#include "globals.h"
|
||||
#include "display/manager.h"
|
||||
@@ -29,6 +32,12 @@ namespace ui {
|
||||
|
||||
class Download;
|
||||
|
||||
// Wrap a user-typed download name pattern in the anchors 'match' expects.
|
||||
std::string create_filter_pattern(const std::string& input);
|
||||
|
||||
// Build the 'match' command the temporary view filter runs against d.name.
|
||||
torrent::Object create_filter_command(const std::string& pattern);
|
||||
|
||||
class DownloadList : public ElementBase {
|
||||
public:
|
||||
typedef display::WindowDownloadList WList;
|
||||
|
||||
@@ -69,6 +69,8 @@ rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \
|
||||
src/test_command_string.h \
|
||||
src/test_setup.cc \
|
||||
src/test_setup.h \
|
||||
src/test_ui_download_list.cc \
|
||||
src/test_ui_download_list.h \
|
||||
src/test_watch_ready_queue.cc \
|
||||
src/test_watch_ready_queue.h
|
||||
|
||||
|
||||
@@ -59,6 +59,23 @@ TestObjectStorage::test_validate_keys() {
|
||||
// The over-long key must not have been stored as the empty key.
|
||||
CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string::from_c_str("")) == m_storage.end());
|
||||
|
||||
// An over-long key must not be truncated into a match either.
|
||||
CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string::from_string(key_max + 'k')) == m_storage.end());
|
||||
|
||||
// set_c_str puts the terminating nul at m_data[size()], so size() has to
|
||||
// stay below max_size for that write to land inside the array.
|
||||
rpc::object_storage::key_type key_long;
|
||||
key_long.set_c_str(std::string(rpc::object_storage::key_size + 1, 'k').c_str());
|
||||
|
||||
CPPUNIT_ASSERT(key_long.size() < rpc::object_storage::key_size);
|
||||
|
||||
m_storage.clear();
|
||||
m_storage.insert_str("test_5", torrent::Object("a"), rpc::object_storage::flag_string_type);
|
||||
|
||||
// insert rejects a key holding a nul-char, so a lookup must not match past one.
|
||||
CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string("test_5\0x", 8)) == m_storage.end());
|
||||
CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string::from_c_str("test_5")) != m_storage.end());
|
||||
|
||||
m_storage.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "test/src/test_ui_download_list.h"
|
||||
|
||||
#include "ui/download_list.h"
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestUiDownloadList);
|
||||
|
||||
void
|
||||
TestUiDownloadList::test_filter_pattern() {
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), ui::create_filter_pattern(""));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(".*linux.*"), ui::create_filter_pattern("linux"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("^linux.*"), ui::create_filter_pattern("^linux"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(".*linux$"), ui::create_filter_pattern("linux$"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(".*linux.*"), ui::create_filter_pattern("LiNuX"));
|
||||
}
|
||||
|
||||
void
|
||||
TestUiDownloadList::test_filter_command() {
|
||||
torrent::Object command = ui::create_filter_command(".*linux.*");
|
||||
|
||||
CPPUNIT_ASSERT(command.is_dict_key());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("match"), command.as_dict_key());
|
||||
|
||||
const torrent::Object::list_type& args = command.as_dict_obj().as_list();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, args.size());
|
||||
CPPUNIT_ASSERT(args.front().is_dict_key());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("d.name"), args.front().as_dict_key());
|
||||
CPPUNIT_ASSERT(args.back().is_string());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(".*linux.*"), args.back().as_string());
|
||||
}
|
||||
|
||||
// A pattern that closes the 'match' argument early and appends a second
|
||||
// command must stay a single inert string argument.
|
||||
void
|
||||
TestUiDownloadList::test_filter_command_does_not_inject() {
|
||||
const std::string pattern = ui::create_filter_pattern("zzz},$d.custom1.set={pwned");
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(".*zzz},$d.custom1.set={pwned.*"), pattern);
|
||||
|
||||
torrent::Object command = ui::create_filter_command(pattern);
|
||||
|
||||
CPPUNIT_ASSERT(command.is_dict_key());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("match"), command.as_dict_key());
|
||||
|
||||
const torrent::Object::list_type& args = command.as_dict_obj().as_list();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL((size_t)2, args.size());
|
||||
CPPUNIT_ASSERT(args.back().is_string());
|
||||
CPPUNIT_ASSERT_EQUAL(pattern, args.back().as_string());
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "test/helpers/test_fixture.h"
|
||||
|
||||
class TestUiDownloadList : public test_fixture {
|
||||
CPPUNIT_TEST_SUITE(TestUiDownloadList);
|
||||
|
||||
CPPUNIT_TEST(test_filter_pattern);
|
||||
CPPUNIT_TEST(test_filter_command);
|
||||
CPPUNIT_TEST(test_filter_command_does_not_inject);
|
||||
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
void test_filter_pattern();
|
||||
void test_filter_command();
|
||||
void test_filter_command_does_not_inject();
|
||||
};
|
||||
Reference in New Issue
Block a user