From 2086e8e780caa81a3281886e26cc57eeedf5a26a Mon Sep 17 00:00:00 2001 From: xirvik Date: Sat, 19 Sep 2026 01:06:31 +0000 Subject: [PATCH] Check the argument count before indexing config comment log args A '# do:log.add_output=debug' line read args[1] past the end of the vector. --- src/setup.cc | 8 +++-- test/Makefile.am | 2 ++ test/src/test_setup.cc | 78 ++++++++++++++++++++++++++++++++++++++++++ test/src/test_setup.h | 18 ++++++++++ 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 test/src/test_setup.cc create mode 100644 test/src/test_setup.h diff --git a/src/setup.cc b/src/setup.cc index 9aefaec6..bd6766ba 100644 --- a/src/setup.cc +++ b/src/setup.cc @@ -86,9 +86,13 @@ config_comment_log(const std::string& command, const std::string& raw_args) { pos = next_pos + 1; } - if (command == "log.add_output") + if (command == "log.add_output") { + if (args.size() != 2) + throw torrent::input_error("Invalid number of arguments."); + log_add_group_output_str(args[0], args[1]); - else if (command == "log.open_file") + + } else if (command == "log.open_file") apply_log_open_str(0, args); else if (command == "log.open_file.flush") apply_log_open_str(log_flag_flush, args); diff --git a/test/Makefile.am b/test/Makefile.am index 4c0879b9..7a4e35fe 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -65,6 +65,8 @@ rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \ src/test_command_path.h \ src/test_command_string.cc \ src/test_command_string.h \ + src/test_setup.cc \ + src/test_setup.h \ src/test_watch_ready_queue.cc \ src/test_watch_ready_queue.h diff --git a/test/src/test_setup.cc b/test/src/test_setup.cc new file mode 100644 index 00000000..9dd8bcc5 --- /dev/null +++ b/test/src/test_setup.cc @@ -0,0 +1,78 @@ +#include "config.h" + +#include "test/src/test_setup.h" + +#include +#include +#include +#include + +#include "setup.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(TestSetup); + +// Linking setup.o pulls in the help printer, which lives in src/main.cc. +void +print_help() {} + +namespace { + +class temp_config_file { +public: + temp_config_file(const std::string& contents) { + char path[] = "/tmp/rtorrent_test_setup_XXXXXX"; + + CPPUNIT_ASSERT(::mkstemp(path) != -1); + m_path = path; + + std::ofstream file(m_path); + file << contents << '\n'; + } + + ~temp_config_file() { ::unlink(m_path.c_str()); } + + const std::string& path() const { return m_path; } + +private: + std::string m_path; +}; + +// The group name must be a valid one, else option_find_string throws before +// the output argument is ever touched. +void +assert_arg_count_error(const std::string& line) { + temp_config_file file(line); + + try { + parse_config_file_comments(file.path()); + } catch (torrent::input_error& e) { + CPPUNIT_ASSERT_EQUAL(std::string("Invalid number of arguments."), std::string(e.what())); + return; + } + + CPPUNIT_FAIL("no torrent::input_error thrown for: " + line); +} + +} // namespace + +void +TestSetup::test_config_comment_log_add_output() { + temp_config_file file("# do:log.add_output=debug,test_output"); + + CPPUNIT_ASSERT_NO_THROW(parse_config_file_comments(file.path())); +} + +void +TestSetup::test_config_comment_log_add_output_no_args() { + assert_arg_count_error("# do:log.add_output="); +} + +void +TestSetup::test_config_comment_log_add_output_one_arg() { + assert_arg_count_error("# do:log.add_output=debug"); +} + +void +TestSetup::test_config_comment_log_add_output_too_many_args() { + assert_arg_count_error("# do:log.add_output=debug,test_output,extra"); +} diff --git a/test/src/test_setup.h b/test/src/test_setup.h new file mode 100644 index 00000000..52c3afe8 --- /dev/null +++ b/test/src/test_setup.h @@ -0,0 +1,18 @@ +#include "test/helpers/test_fixture.h" + +class TestSetup : public test_fixture { + CPPUNIT_TEST_SUITE(TestSetup); + + CPPUNIT_TEST(test_config_comment_log_add_output); + CPPUNIT_TEST(test_config_comment_log_add_output_no_args); + CPPUNIT_TEST(test_config_comment_log_add_output_one_arg); + CPPUNIT_TEST(test_config_comment_log_add_output_too_many_args); + + CPPUNIT_TEST_SUITE_END(); + +public: + void test_config_comment_log_add_output(); + void test_config_comment_log_add_output_no_args(); + void test_config_comment_log_add_output_one_arg(); + void test_config_comment_log_add_output_too_many_args(); +};