From 49a199bb51fc00659f8134e5b16f5d36364b0554 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 11 Apr 2017 18:30:42 +1200 Subject: torcontrol: Handle escapes in Tor QuotedStrings https://trac.torproject.org/projects/tor/ticket/14999 is tracking an encoding bug with the Tor control protocol, where many of the QuotedString instances that Tor outputs are in fact CStrings, but it is not documented which ones are which. https://spec.torproject.org/control-spec section 2.1.1 provides a future-proofed rule for handing QuotedStrings, which this commit implements. This commit merges all six commits from https://github.com/zcash/zcash/pull/2251 --- src/test/torcontrol_tests.cpp | 45 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'src/test') diff --git a/src/test/torcontrol_tests.cpp b/src/test/torcontrol_tests.cpp index 68516599d9..b7affaacde 100644 --- a/src/test/torcontrol_tests.cpp +++ b/src/test/torcontrol_tests.cpp @@ -119,29 +119,60 @@ BOOST_AUTO_TEST_CASE(util_ParseTorReplyMapping) {"Foo", "Bar Baz"}, }); - // Escapes (which are left escaped by the parser) + // Escapes CheckParseTorReplyMapping( "Foo=\"Bar\\ Baz\"", { - {"Foo", "Bar\\ Baz"}, + {"Foo", "Bar Baz"}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\Baz\"", { - {"Foo", "Bar\\Baz"}, + {"Foo", "BarBaz"}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\@Baz\"", { - {"Foo", "Bar\\@Baz"}, + {"Foo", "Bar@Baz"}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\\"Baz\" Spam=\"\\\"Eggs\\\"\"", { - {"Foo", "Bar\\\"Baz"}, - {"Spam", "\\\"Eggs\\\""}, + {"Foo", "Bar\"Baz"}, + {"Spam", "\"Eggs\""}, }); CheckParseTorReplyMapping( "Foo=\"Bar\\\\Baz\"", { - {"Foo", "Bar\\\\Baz"}, + {"Foo", "Bar\\Baz"}, }); + // C escapes + CheckParseTorReplyMapping( + "Foo=\"Bar\\nBaz\\t\" Spam=\"\\rEggs\" Octals=\"\\1a\\11\\17\\18\\81\\377\\378\\400\\2222\" Final=Check", { + {"Foo", "Bar\nBaz\t"}, + {"Spam", "\rEggs"}, + {"Octals", "\1a\11\17\1" "881\377\37" "8\40" "0\222" "2"}, + {"Final", "Check"}, + }); + CheckParseTorReplyMapping( + "Valid=Mapping Escaped=\"Escape\\\\\"", { + {"Valid", "Mapping"}, + {"Escaped", "Escape\\"}, + }); + CheckParseTorReplyMapping( + "Valid=Mapping Bare=\"Escape\\\"", {}); + CheckParseTorReplyMapping( + "OneOctal=\"OneEnd\\1\" TwoOctal=\"TwoEnd\\11\"", { + {"OneOctal", "OneEnd\1"}, + {"TwoOctal", "TwoEnd\11"}, + }); + + // Special handling for null case + // (needed because string comparison reads the null as end-of-string) + BOOST_TEST_MESSAGE(std::string("CheckParseTorReplyMapping(Null=\"\\0\")")); + auto ret = ParseTorReplyMapping("Null=\"\\0\""); + BOOST_CHECK_EQUAL(ret.size(), 1); + auto r_it = ret.begin(); + BOOST_CHECK_EQUAL(r_it->first, "Null"); + BOOST_CHECK_EQUAL(r_it->second.size(), 1); + BOOST_CHECK_EQUAL(r_it->second[0], '\0'); + // A more complex valid grammar. PROTOCOLINFO accepts a VersionLine that // takes a key=value pair followed by an OptArguments, making this valid. // Because an OptArguments contains no semantic data, there is no point in -- cgit v1.2.3