aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/epee/src/hex.cpp8
-rw-r--r--src/rpc/message.cpp15
-rw-r--r--tests/unit_tests/CMakeLists.txt4
-rw-r--r--tests/unit_tests/epee_utils.cpp3
-rw-r--r--tests/unit_tests/zmq_rpc.cpp55
5 files changed, 77 insertions, 8 deletions
diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp
index 558983f7e..b654a0269 100644
--- a/contrib/epee/src/hex.cpp
+++ b/contrib/epee/src/hex.cpp
@@ -84,7 +84,7 @@ namespace epee
return write_hex(out, src);
}
- std::vector<uint8_t> from_hex::vector(boost::string_ref src)
+ std::vector<uint8_t> from_hex::vector(const boost::string_ref src)
{
// should we include a specific character
auto include = [](char input) {
@@ -104,7 +104,7 @@ namespace epee
result.reserve(count / 2);
// the data to work with (std::string is always null-terminated)
- auto data = src.data();
+ auto data = src.begin();
// convert a single hex character to an unsigned integer
auto char_to_int = [](const char *input) {
@@ -130,9 +130,9 @@ namespace epee
};
// keep going until we reach the end
- while (data[0] != '\0') {
+ while (data != src.end()) {
// skip unwanted characters
- if (!include(data[0])) {
+ if (!include(*data)) {
++data;
continue;
}
diff --git a/src/rpc/message.cpp b/src/rpc/message.cpp
index 158b58005..689eb5e33 100644
--- a/src/rpc/message.cpp
+++ b/src/rpc/message.cpp
@@ -52,6 +52,16 @@ constexpr const char id_field[] = "id";
constexpr const char method_field[] = "method";
constexpr const char params_field[] = "params";
constexpr const char result_field[] = "result";
+
+const rapidjson::Value& get_method_field(const rapidjson::Value& src)
+{
+ const auto member = src.FindMember(method_field);
+ if (member == src.MemberEnd())
+ throw cryptonote::json::MISSING_KEY{method_field};
+ if (!member->value.IsString())
+ throw cryptonote::json::WRONG_TYPE{"Expected string"};
+ return member->value;
+}
}
rapidjson::Value Message::toJson(rapidjson::Document& doc) const
@@ -120,7 +130,7 @@ FullMessage::FullMessage(const std::string& json_string, bool request)
if (request)
{
- OBJECT_HAS_MEMBER_OR_THROW(doc, method_field)
+ get_method_field(doc); // throws on errors
OBJECT_HAS_MEMBER_OR_THROW(doc, params_field)
}
else
@@ -151,8 +161,7 @@ std::string FullMessage::getJson()
std::string FullMessage::getRequestType() const
{
- OBJECT_HAS_MEMBER_OR_THROW(doc, method_field)
- return doc[method_field].GetString();
+ return get_method_field(doc).GetString();
}
rapidjson::Value& FullMessage::getMessage()
diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index 96825f54f..17d6dfd9f 100644
--- a/tests/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -92,7 +92,8 @@ set(unit_tests_sources
ringdb.cpp
wipeable_string.cpp
is_hdd.cpp
- aligned.cpp)
+ aligned.cpp
+ zmq_rpc.cpp)
set(unit_tests_headers
unit_tests_utils.h)
@@ -105,6 +106,7 @@ target_link_libraries(unit_tests
ringct
cryptonote_protocol
cryptonote_core
+ daemon_messages
blockchain_db
lmdb_lib
rpc
diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp
index 6f887afda..a4b339295 100644
--- a/tests/unit_tests/epee_utils.cpp
+++ b/tests/unit_tests/epee_utils.cpp
@@ -840,6 +840,9 @@ TEST(FromHex, String)
// decoding it this way also, ignoring spaces and colons between the numbers
hex.assign("00:ff 0f:f0");
EXPECT_EQ(source, epee::from_hex::vector(hex));
+
+ hex.append("f0");
+ EXPECT_EQ(source, epee::from_hex::vector(boost::string_ref{hex.data(), hex.size() - 2}));
}
TEST(ToHex, Array)
diff --git a/tests/unit_tests/zmq_rpc.cpp b/tests/unit_tests/zmq_rpc.cpp
new file mode 100644
index 000000000..af1f1608b
--- /dev/null
+++ b/tests/unit_tests/zmq_rpc.cpp
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <gtest/gtest.h>
+
+#include "rpc/message.h"
+#include "serialization/json_object.h"
+
+TEST(ZmqFullMessage, InvalidRequest)
+{
+ EXPECT_THROW(
+ (cryptonote::rpc::FullMessage{"{\"jsonrpc\":\"2.0\",\"id\":0,\"params\":[]}", true}),
+ cryptonote::json::MISSING_KEY
+ );
+ EXPECT_THROW(
+ (cryptonote::rpc::FullMessage{"{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":3,\"params\":[]}", true}),
+ cryptonote::json::WRONG_TYPE
+ );
+}
+
+TEST(ZmqFullMessage, Request)
+{
+ static constexpr const char request[] = "{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"foo\",\"params\":[]}";
+ EXPECT_NO_THROW(
+ (cryptonote::rpc::FullMessage{request, true})
+ );
+
+ cryptonote::rpc::FullMessage parsed{request, true};
+ EXPECT_STREQ("foo", parsed.getRequestType().c_str());
+}